c语言内存四区,指针、数组、结构体的存储

c程序内存四区的个人理解 代码是vc6.0运行结果。

栈:由编译器自动分配释放,存放函数的参数值,局部变量等, 存放在这里的变量地址不能作为返回值返回,因为这部分分配的内存会被析构,当你访问这块内存时,这块内存可能已经不存在了,只剩下返回的首地址了。
比如:
char *fun()
{
    char a[];//临时变量 存放在栈区
    char *p = NULL;
    p = "dssda";//存储在常量区 可以返回 但是被操作系统保护 不能强制修改这块内存的值。
    return a;
}
堆区:一般由程序员分配释放(动态内存申请和释放malloc/free),若程序员不释放,程序结束时 可有操作系统回收

全局去:全局变量和静态变量存放在此,里面细分有一个常量区,字符串和其他常量也放在此处,由操作系统释放。

代码区:存放函数体的二进制代码
//main.cpp
    int a=0;      //全局初始化区
    char *p1;     //全局未初始化区
    main()
    {
     int b;栈
     char s[]="abc";     //栈
     char *p2;           //栈
     char *p3="123456";     //123456\0在常量区,p3在栈上。
     static int c=0;     //全局(静态)初始化区
     p1 = (char*)malloc(10);
     p2 = (char*)malloc(20);     //分配得来得10和20字节的区域就在堆区。
     strcpy(p1,"123456");     //123456\0放在常量区,编译器可能会将它与p3所向"123456"优化成一个
地方。
}
例题:
int main()
{
    char *p = "abcd";
    char q[] = "abcd";
    char *p1 = (char *)malloc(10);
    char p2[] = {1,2,3,4};

    strcpy(p1,"abcd");

    printf("%d  %d %s\n",&p,p,p);

    printf("%d %d %s\n",&q,q,q);
    printf("%d  %d %s\n",&p1,p1,p1);
    
    printf("p: %d\n",sizeof(p));
    printf("q: %d\n",sizeof(q));
    printf("q: %d\n",sizeof(p1));
    printf("q: %d\n",sizeof(p2));
    return 0;
}
运行结果:
1703740  4333636 (全局区)abcd
1703732 1703732 (栈区)abcd
1703728  9320648(堆区) abcd
为什么指针*p指的内存区域不能改变而q[]可以改变?
答:从上面程序运行结果可以看到char *p分配的地址是1703740(栈区)“”abcd“”分配的地址在4333636(全局区的常量区中)。char q[] 1703732(栈区)“”“abcd”(也是在全局区 但是会被copy到和char q[]在同一个栈区地址),全局区不可以随意改变,栈区可以。
划分内存四区的意义:
C语言程序中,根据是局部变量,全局变量, 常量还是通过malloc等类似的函数分配内存空间, 把他们放到对应的内存区中.这样就赋予了这些变量或常量不同的生命周期, 不同的释放方式. 根据我们程序的需要,我们在编码过程中,声明不同的变量类型, 使他们有不同的声明长度, 不同的释放方式,给我们更大的灵活编程

c语言内存四区,指针、数组、结构体的存储_第1张图片

c语言内存四区,指针、数组、结构体的存储_第2张图片

 

c语言内存四区,指针、数组、结构体的存储_第3张图片

c语言内存四区,指针、数组、结构体的存储_第4张图片

 

c语言内存四区,指针、数组、结构体的存储_第5张图片c语言内存四区,指针、数组、结构体的存储_第6张图片

 

 

 

你可能感兴趣的:(C语言)