免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
打印 上一主题 下一主题

临时变量,static,malloc分别申请在哪里? [复制链接]

论坛徽章:
0
21 [报告]
发表于 2005-04-15 02:17 |只看该作者

临时变量,static,malloc分别申请在哪里?

原帖由 "gerysand" 发表:
对于static和global变量放在data段里应该没有什么疑问,local变量放在stack里也没有什么疑问,但是对于heap(堆)的malloc数据一直不怎么明白。heap到底处于进程中的哪部分空间?

曾经有个static变量,我误以为是..........


到底处于进程中的哪部分空间, 是由OS来定的. 还看执行文件的大小, 但总是TEXT/DATA段放好之后决定的.
没错,malloc只能管理HEAP上的东西, 如果FREE一块static memory, malloc会把它当一般HEAP blocck出理. 比如, 读取指针前一字来决定FREE的内存大小(libc 在malloc时写上去的). 并与前后FREE的内存合并等. 可想而知, 下面不知会出什么乱子. 所以任何不当内存操作(比如double free, overrun, underrun), 不限于free static变量, 都回出错. 更糟糕的是, 往往出错在程序后面, undefined(有时不会seg fault), 这真是程序员的噩梦.

论坛徽章:
0
22 [报告]
发表于 2005-04-15 06:40 |只看该作者

临时变量,static,malloc分别申请在哪里?

原帖由 "Annihilus" 发表:
使用C 语言或汇编语言编写的内容最终可以分为三个区域
CODE section 存储程序代码和ROM数据
DATA section 存储带初始值的读写数据
BSS section 存储没有初始值的数据
例如:
int a; <- 存放在BSS 段
int b=..........


这位兄弟是做嵌入系统的吧. 我对此没有经验. 不过segment 和 section是不同的概念, 至少在我们现在讨论的范畴里.
系统的LOADER只管段, 它看可执行程序就是分几段, CODE(TEXT), DATA,HEAP. 它根据可执行程序要求建立段, 把程序从载体(ROM或磁盘)map到进程. 然后控制转给LINKER. LINKER看程序就是区:data,bss,got,reloc,debug,....

一般TEXT段里有如下区(linux):
text, rodata,hash,dynstr,dynsym,rel,got,plt
DATA 段里有如下区:
data,bss,got,dynamic

readelf -a 会县示所有可执行程序包涵的段和区的HEADER.

论坛徽章:
0
23 [报告]
发表于 2005-04-15 17:45 |只看该作者

临时变量,static,malloc分别申请在哪里?

原帖由 "Alligator27" 发表:

共享库的全局数据不会在STACK上, 它们自己有DATA段. 看/proc/pid/maps里libc的DATA段就很清楚了.


我是从TLDP上的一篇LinuxKernelAnalysisHOWTO文档中得出这个印象的:
We can also say that an interTask page fault never occurs, because each Task uses a set of Page Tables that are different for each Task. There are some cases where different Tasks point to same Page Tables, like shared libraries: this is needed to reduce memory usage; remember that shared libraries are CODE only cause all datas are stored into actual Task stack.

记得当时写小程序试验了一下,证明是正确的。那个程序弄丢了,要不你试验一下?(兄弟现在有点忙)
咱们讨论清楚

论坛徽章:
0
24 [报告]
发表于 2005-04-16 00:36 |只看该作者

临时变量,static,malloc分别申请在哪里?

原帖由 "albcamus" 发表:

记得当时写小程序试验了一下,证明是正确的。那个程序弄丢了,要不你试验一下?(兄弟现在有点忙)
咱们讨论清楚


关于这点, 我可以负责任地说, shared lib的变量不会在STACK.  :wink:
这篇文章里的TASK STACK, 不应是我们讨论的STACK. 能否把整个文章的URL给我. 想看一下上下文.
想到以前我闹的笑话, 老板要我编一个库的DEBUGGER. 我就用自己的DEBUGGER进程来看另一个用户进程的同样库的全局变量, 看了半天不明白为什么变量值不对. 可见我当时对VMM一无所知.

论坛徽章:
0
25 [报告]
发表于 2005-04-16 13:31 |只看该作者

临时变量,static,malloc分别申请在哪里?

http://www.tldp.org/HOWTO/KernelAnalysis-HOWTO.html

论坛徽章:
0
26 [报告]
发表于 2005-04-16 21:37 |只看该作者

临时变量,static,malloc分别申请在哪里?

谢谢楼上, 我看了这个文档. 个人看法, 作者把DATA和STACK归为一个段. 所以文章中不刻意区分它们. "remember that shared libraries are CODE only (be)cause all datas are stored into actual Task user data/stack."

论坛徽章:
0
27 [报告]
发表于 2005-04-18 15:34 |只看该作者

临时变量,static,malloc分别申请在哪里?

[quote]原帖由 "Alligator27"]stack."[/quote 发表:


兄弟你说的不对哦
我又试验了一遍,证明so文件中data段的数据确实在每个使用它的程序的STACK中。

其实可以想一下,倘若不是这样的话,共享库中的data又不是只读的,那多个进程进行读写时难道不需要同步? 因此就需要映射到他们自己的(别的进程无法知道的)地址,data是不行的,因为那是编译时初始化的;bss也不行,因为编译时必须知道其大小……因此,也只有STACK差强人意了

论坛徽章:
0
28 [报告]
发表于 2005-04-18 20:18 |只看该作者

临时变量,static,malloc分别申请在哪里?

仍然在STACK里,只不过是在各个进程各自的STACK空间里。

论坛徽章:
0
29 [报告]
发表于 2005-04-18 21:36 |只看该作者

临时变量,static,malloc分别申请在哪里?

albcamus:怎么证明的?好东西拿出来让大家分享啊

论坛徽章:
0
30 [报告]
发表于 2005-04-19 05:17 |只看该作者

临时变量,static,malloc分别申请在哪里?

原帖由 "albcamus" 发表:


兄弟你说的不对哦
我又试验了一遍,证明so文件中data段的数据确实在每个使用它的程序的STACK中。

其实可以想一下,倘若不是这样的话,共享库中的data又不是只读的,那多个进程进行读写时难道不需要同步? ..........


OK. 我写了一段程序来证明前面说的是负责任的.

#include <unistd.h>;
#include <stdio.h>;
#include <stdlib.h>;

int gInt=0;

int main()
{
        int lVarOnStack = 0;
        printf("&lVarOnStack = 0x%x\n", &lVarOnStack);
        printf("stderr       = 0x%x\n", (void*)stderr);

        char lCmdLine[128];
        sprintf(lCmdLine, "cat /proc/%ld/maps", getpid());
        system(lCmdLine);

        sleep(1);
        //done
        return 0;
}

在LINUX上,
>;g++ -m32 -g foo.C
>;a.out

&lVarOnStack = 0xffffda3c
stderr       = 0xa0220e00
0000000008048000-0000000008049000 r-xp 0000000000000000 00:5f 5684492    /home/y/projects/tmp/a.out
0000000008049000-000000000804a000 rwxp 0000000000000000 00:5f 5684492    /home/y/projects/tmp/a.out
0000000040000000-0000000040015000 r-xp 0000000000000000 08:02 524361     /lib/ld-2.3.2.so
0000000040015000-0000000040016000 rwxp 0000000000015000 08:02 524361     /lib/ld-2.3.2.so
00000000a0000000-00000000a0001000 rwxp 0000000000000000 00:00 0
00000000a000f000-00000000a00b8000 r-xp 0000000000000000 08:02 1245273    /usr/lib/libstdc++.so.5.0.3
00000000a00b8000-00000000a00bd000 rwxp 00000000000a8000 08:02 1245273    /usr/lib/libstdc++.so.5.0.3
00000000a00bd000-00000000a00c3000 rwxp 0000000000000000 00:00 0
00000000a00c3000-00000000a00e4000 r-xp 0000000000000000 08:02 2162699    /lib/tls/libm-2.3.2.so
00000000a00e4000-00000000a00e5000 rwxp 0000000000021000 08:02 2162699    /lib/tls/libm-2.3.2.so
00000000a00e5000-00000000a00ed000 r-xp 0000000000000000 08:02 524290     /lib/libgcc_s-3.2.3-20030829.so.1
00000000a00ed000-00000000a00ee000 rwxp 0000000000007000 08:02 524290     /lib/libgcc_s-3.2.3-20030829.so.1
00000000a00ee000-00000000a0220000 r-xp 0000000000000000 08:02 2162696    /lib/tls/libc-2.3.2.so
00000000a0220000-00000000a0223000 rwxp 0000000000132000 08:02 2162696    /lib/tls/libc-2.3.2.so
00000000a0223000-00000000a0227000 rwxp 0000000000000000 00:00 0
00000000ffffc000-00000000ffffe000 rwxp fffffffffffff000 00:00 0

临时变量lVarOnStack地址0xffffda3c在STACK上(00000000ffffc000-00000000ffffe000). 而libc的全局变量stderr地址0xa0220e00是在libc的DATA段里(00000000a0220000-00000000a0223000). 不是在STACK里.

STACK段的上端是固定的, 下端随程序而变动. 如果把libc的全局变量放在里面, 放哪能使它的生命根进程一样长呢?

每个shared lib调进时(不管是ld联接的, 还是dlopen的), loader会根据其要求的大小(compiler 决定)创立CODE, DATA(包括.data 和.bss section)段. 这点在用dlopen时特别明显.

以上观点与各位商榷. 加一点, 如果错了, 我也负不了责. :wink:
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP