linux下进程内存布局及变量存储位置检查

进程的内存布局如下(虚拟内存):

              

它们分别从低地址向高地址增长

在linux中,存在三个全局符号:etext, edata, end分别指向文本段,初始化数据段,未初始化数据段结尾处的下一字节的地址。

所以我们可以在c程序中声明这些变量,然后定义一些变量再查看其地址是否在对应的地址范围内,可得出其变量被存储在哪个区中。

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

extern char etext, edata, end;

int a = 10;

void func()
{
    int d = 666; //栈
    printf("func =  %p\n", func);  //文本段
    printf("局部变量d, &d =    %p\n", &d);
}

int main()
{
    int b = 100;  //栈区

    int *p = (int*)&edata;

    int *c = (int*)malloc(sizeof(int));  //堆

    *c = 99;

    printf("etext = %10p\nedata = %10p\nend =   %10p\n", &etext, &edata, &end);

    printf("全局变量a, &a =    %p\n", &a);
    printf("局部变量b, &b =    %p\n", &b);
    printf("堆分配的内存, &(*c) = %p\n", &(*c));
    printf("main  = %p\n", main);

    printf("a = %d\n", *(--p));

    func();

    return 0;
}

输出如下:

etext =   0x557ed79928ed
edata = 0x557ed7b93014
end =    0x557ed7b93018
全局变量a, &a =  0x557ed7b93010
局部变量b, &b =  0x7fff14f77454
堆分配的内存, &(*c) = 0x557ed7f6e260
main  = 0x557ed799275f
a = 10
func =  0x557ed79926fa
局部变量d, &d = 0x7fff14f77434                                

可以看出:

对于main: 0x557ed799275f

  func:  0x557ed79926fa , 它们的地址都小于

 etext:     0x557ed79928ed

所以可知main和func函数,都存储在文本区中。

全局变量a : 0x557ed7b93010

大于etext  : 0x557ed79928ed

小于edata: 0x557ed7b93014

所以知道初始化的全局变量a在初始化数据区中,

其它以此类推。

原文地址:https://www.cnblogs.com/ilove-haha/p/12388325.html

时间: 2024-08-10 18:13:34

linux下进程内存布局及变量存储位置检查的相关文章

Linux C进程内存布局

当程序文件运行为进程时,进程在内存中获得空间.这个空间是进程自己的内存空间.每个进程空间按照如下方式分为不同区域: 进程内存空间布局图 text:代码段.存放的是程序的全部代码(指令),来源于二进制可执行文件中的代码部分 initialized data(简称data段)和uninitialized data(简称bss段)组成了数据段.其中data段存放的是已初始化全局变量和已初始化static局部变量,来源于二进制可执行文件中的数据部分: bss段存放的是未初始化全局变量和未初始化stati

java+内存分配及变量存储位置的区别

Java内存分配与管理是Java的核心技术之一,之前我们曾介绍过Java的内存管理与内存泄露以及Java垃圾回收方面的知识,今天我们再次深入Java核心,详细介绍一下Java在内存分配方面的知识.一般Java在内存分配时会涉及到以下区域: ◆寄存器:我们在程序中无法控制 ◆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中(new 出来的对象) ◆堆:存放用new产生的数据 ◆静态域:存放在对象中用static定义的静态成员 ◆常量池:存放常量 ◆非RAM存储:硬盘等永久

内存分配及变量存储位置(堆、栈、方法区常量池、方法区静态区)

转载来源:http://www.cnblogs.com/protected/p/6419217.html 侵删! 程序运行时,有六个地方都可以保存数据: 1. 寄存器:这是最快的保存区域,因为它位于和其他所有保存方式不同的地方:处理器内部.然而,寄存器的数量十分有限,所以寄存器是根据需要由编译器分配.我们对此没有直接的控制权,也不可能在自己的程序里找到寄存器存在的任何踪迹. 2. 堆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中(new 出来的对象).驻留于常规RAM

Java内存分配及变量存储位置实例讲解

Java内存分配与管理是Java的核心技术之一,之前我们曾介绍过Java的内存管理与内存泄露以及Java垃圾回收方面的知识,今天我们再次深入Java核心,详细介绍一下Java在内存分配方面的知识.一般Java在内存分配时会涉及到以下区域: ◆寄存器:我们在程序中无法控制 ◆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中(new 出来的对象) ◆堆:存放用new产生的数据 ◆静态域:存放在对象中用static定义的静态成员 ◆常量池:存放常量 ◆非RAM存储:硬盘等永久

java+内存分配及变量存储位置的区别[转]

原文来自:http://blog.csdn.net/rj042/article/details/6871030#comments Java内存分配与管理是Java的核心技术之一,之前我们曾介绍过Java的内存管理与内存泄露以及Java垃圾回收方面的知识,今天我们再次深入Java核心,详细介绍一下Java在内存分配方面的知识.一般Java在内存分配时会涉及到以下区域: ◆寄存器:我们在程序中无法控制 ◆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中(new 出来的对象)

Java:(转载收藏它处):java+内存分配及变量存储位置的区别

Java内存分配与管理是Java的核心技术之一,之前我们曾介绍过Java的内存管理与内存泄露以及Java垃圾回收方面的知识,今天我们再次深入Java核心,详细介绍一下Java在内存分配方面的知识.一般Java在内存分配时会涉及到以下区域: ◆寄存器:我们在程序中无法控制 ◆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中(new 出来的对象) ◆堆:存放用new产生的数据 ◆静态域:存放在对象中用static定义的静态成员 ◆常量池:存放常量 ◆非RAM存储:硬盘等永久

【网络编程基础】Linux下进程通信方式(共享内存,管道,消息队列,Socket)

在网络课程中,有讲到Socket编程,对于tcp讲解的环节,为了加深理解,自己写了Linux下进程Socket通信,在学习的过程中,又接触到了其它的几种方式.记录一下. 管道通信(匿名,有名) 管道通信,在一个进程之中,只能单一的对其写或者是读,而不可以及执行写操作又执行读操作.这一点,我们可以将其想象成我们的水管,分别连着不同的两端,在有水流的时候,一端只能进行输入,另一端只能进行输出,而不可以同时输入和输出. 管道又分为有名管道和匿名管道,两者的区别在于对于匿名管道,其只能在具有亲缘关系的父

一个由进程内存布局异常引起的问题

一个由进程内存布局异常引起的问题 前段时间业务反映某类服务器上更新了 bash 之后,ssh 连上去偶发登陆失败,客户端吐出错误信息如下所示:图 - 0 该版本 bash 为部门这边所定制,但实现上并没有改动原有逻辑,只是加入了些监控功能,那么这些错误从哪里来呢? 是 bash 的锅吗 从上面的错误信息可以猜测,异常是 bash 在启动过程中分配内存失败所导致,看起来像是某些情况下该进程错误地进行了大量内存分配,最后导致内存不足,要确认这个事情比较简单,动态内存分配到系统调用这一层上主要就两种方

linux下的内存分布

周日讲了32位linux下的内存分布 还有关于C语言中的extern和static的用法 内存的最高1G是用作系统保留,接下来是占空间,在靠近3G的那一块 再下来是堆空间,之后是bss区,未初始化的静态变量区 然后是Rw data区 Ro data区,主要用作存储字符串类型 接下来是代码段,又名txt正文段 0xffffffff 内核 0xbfff ffff 栈 堆 bss区 rw data ro data 代码段 0x00000000 接下来就是验证 1 #include <stdio.h>