免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1715 | 回复: 9
打印 上一主题 下一主题

[Linux] Linux 环境编程中,一个关于内存的问题,比较有深度 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-02-01 13:37 |只看该作者 |倒序浏览
#include<stdio.h>
#include<sys/types.h>
#include<pwd.h>
#include <unistd.h>
#include <stdlib.h>

int global = 10;

int main( int argc,char *argv[])
{
        struct passwd *strpwd;
        strpwd=getpwuid(getuid());
        printf("pwd address is %p\n",(char *)strpwd);
        //printf("real user name is: %s\n", strpwd->pw_name);

        strpwd=getpwuid(geteuid());
        //printf("effective user name is: %s\n", strpwd->pw_name);
        printf("pwd address is %p\n",strpwd);

        char *p = (char *) malloc(5);
        printf("heap address is %p\n",p);
       
        printf("global: %p\n",&global);
       
        return 0;
}


这里的一个思考是:getpwuid 是根据用户uid返回一个passwd 结构的指针,可是这个真正的结构是存放在哪里的呢?
按照平常的编程习惯,加入我们想要得到一个结构的话:我们应该自己先在主调函数中分配这样一个结构体,然后将结构体的指针交给被调函数去处理,处理完了以后,主调函数中的这个结构体内就存放了我们需要的最终数据。

可是现在getpwuid 函数是:它给你返回一个passwd 结构体的指针,可是这个结构体在哪里存放却让人不明不白。首先这个结构体肯定不可能在getpwuid 这个函数中分配,因为栈中分配的内存,函数返回时立即失效。再次,这个结构体应该也不至于是malloc 分配的,如果真是malloc分配在堆中的话,被调函数分配,难道还要主调函数去释放不成,主调函数压根就不应该关心这些。
那会不会是在全局变量中呢?或者是在内核区中?

而且unix 环境编程中这样的例子还有很多,比如读取目录项的的函数 readdir() 函数返回一个 dirent 结构体指针,可是这个结构体存放的位置,也是让人疑惑不堪。


在这个例子中:我专门用printf("%p") 将令人疑惑的结构体地址打印出来了,并且跟一个malloc 函数的返回地址,还有一个全局变量的地址做了一个比较。打印出来的地址如下所示,给大家分析作为参考。会发现两次getpwuid的返回地址都是相同的。
下面是输出:

pwd address is 0x7f7f32debe40
pwd address is 0x7f7f32debe40        <<注意这个地址,和上一个地址相同
heap address is 0x1b55420
global: 0x601060

论坛徽章:
46
2015小元宵徽章
日期:2015-03-06 15:58:18羊年新春福章
日期:2015-04-14 10:37:422015年亚洲杯之阿曼
日期:2015-04-14 10:41:50NBA常规赛纪念章
日期:2015-05-04 22:32:03NBA季后赛大富翁
日期:2015-05-04 22:34:11菠菜明灯
日期:2015-05-04 22:35:49新奥尔良黄蜂
日期:2015-05-04 22:49:2315-16赛季CBA联赛之广夏
日期:2015-12-11 15:02:342015年亚洲杯之巴勒斯坦
日期:2015-03-04 19:56:562015年亚洲杯之阿联酋
日期:2015-03-04 11:19:04休斯顿火箭
日期:2015-03-02 16:32:11纽约尼克斯
日期:2015-03-02 16:09:04
2 [报告]
发表于 2015-02-02 10:00 |只看该作者
应该是在堆中,可以找源码看

论坛徽章:
4
双子座
日期:2014-08-28 10:08:002015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:58:112015年亚洲杯之阿联酋
日期:2015-03-13 03:25:15
3 [报告]
发表于 2015-02-02 10:35 |只看该作者
static的指针是可以返回的

求职 : 机器学习
论坛徽章:
79
2015年亚洲杯纪念徽章
日期:2015-05-06 19:18:572015七夕节徽章
日期:2015-08-21 11:06:172015亚冠之阿尔纳斯尔
日期:2015-09-07 09:30:232015亚冠之萨济拖拉机
日期:2015-10-21 08:26:3915-16赛季CBA联赛之浙江
日期:2015-12-30 09:59:1815-16赛季CBA联赛之浙江
日期:2016-01-10 12:35:21技术图书徽章
日期:2016-01-15 11:07:2015-16赛季CBA联赛之新疆
日期:2016-02-24 13:46:0215-16赛季CBA联赛之吉林
日期:2016-06-26 01:07:172015-2016NBA季后赛纪念章
日期:2016-06-28 17:44:45黑曼巴
日期:2016-06-28 17:44:4515-16赛季CBA联赛之浙江
日期:2017-07-18 13:41:54
4 [报告]
发表于 2015-02-02 12:32 |只看该作者
  1. 比如读取目录项的的函数 readdir() 函数返回一个 dirent 结构体指针
复制代码
我在查Linux/Unix系统编程手册的过程中,发现有这样的表述
  1. 指向静态分配而获得的dirent类型结构,每次调用readdir()都会覆盖该结构。
复制代码
据此可知,该指针指向的事实上应该是库中的一个静态变量,也就是static类型的变量。

求职 : 机器学习
论坛徽章:
79
2015年亚洲杯纪念徽章
日期:2015-05-06 19:18:572015七夕节徽章
日期:2015-08-21 11:06:172015亚冠之阿尔纳斯尔
日期:2015-09-07 09:30:232015亚冠之萨济拖拉机
日期:2015-10-21 08:26:3915-16赛季CBA联赛之浙江
日期:2015-12-30 09:59:1815-16赛季CBA联赛之浙江
日期:2016-01-10 12:35:21技术图书徽章
日期:2016-01-15 11:07:2015-16赛季CBA联赛之新疆
日期:2016-02-24 13:46:0215-16赛季CBA联赛之吉林
日期:2016-06-26 01:07:172015-2016NBA季后赛纪念章
日期:2016-06-28 17:44:45黑曼巴
日期:2016-06-28 17:44:4515-16赛季CBA联赛之浙江
日期:2017-07-18 13:41:54
5 [报告]
发表于 2015-02-02 12:33 |只看该作者
和这样比较像的还有errno这个常见的错误诊断的变量

论坛徽章:
0
6
发表于 2015-02-02 15:36
现在大概可以推断出,这样的变量是在函数中用static 分配的。
也就是说在内存中是和全局变量放在同一块区域的。
指向静态分配而获得的dirent类型结构,每次调用readdir()都会覆盖该结构 。这个跟我的实验结果也就吻合了,上面代码里两次打印的 passwd 结构体的地址都相同。

至于说和errno相同,我觉得肯定是不同的。errno应该是一个全局变量,无论执行哪个程序,这个全局变量都是存在的。
而类似的dirent,passwd等结构,应该是使用类似的读取函数时,函数中有相应的static 类型变量,这样编译时才会在静态变量区分配吧。

回复 5# zsszss0000


   

论坛徽章:
0
7
发表于 2015-02-02 15:37
还有,谢谢你帮忙查文档,帮忙一起讨论
回复 4# zsszss0000


   

论坛徽章:
0
8 [报告]
发表于 2015-02-02 15:38 |只看该作者
我要能看懂源码,就不来提问了。
回复 2# super皮波


   

论坛徽章:
0
9 [报告]
发表于 2015-02-02 15:39 |只看该作者
static 这种的我也想过,函数中static 变量和 全局变量应该都是放在全局静态区的。
所以我上面专门打印出了一个global 变量的地址,和返回的passwd 结构体的指针做了一个比较,感觉内存地址差的有点远。

回复 3# weishuo1999


   

求职 : 机器学习
论坛徽章:
79
2015年亚洲杯纪念徽章
日期:2015-05-06 19:18:572015七夕节徽章
日期:2015-08-21 11:06:172015亚冠之阿尔纳斯尔
日期:2015-09-07 09:30:232015亚冠之萨济拖拉机
日期:2015-10-21 08:26:3915-16赛季CBA联赛之浙江
日期:2015-12-30 09:59:1815-16赛季CBA联赛之浙江
日期:2016-01-10 12:35:21技术图书徽章
日期:2016-01-15 11:07:2015-16赛季CBA联赛之新疆
日期:2016-02-24 13:46:0215-16赛季CBA联赛之吉林
日期:2016-06-26 01:07:172015-2016NBA季后赛纪念章
日期:2016-06-28 17:44:45黑曼巴
日期:2016-06-28 17:44:4515-16赛季CBA联赛之浙江
日期:2017-07-18 13:41:54
10 [报告]
发表于 2015-02-02 16:49 |只看该作者
但是书里面明确写的是静态变量啊,这个返回的数值是库函数中的,是不是这个原因导致的呢?回复 9# 呼呼的id


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP