c语言内存四区、数据存储范围和内存存储方向

(1)代码区通常是共享只读(代码无法修改)的,即可以被其他的程序调用,例如运行两个qq,除了数据不一样,代码都是一样的,

每次运行qq,都会将代码和数据加载到内存中,除了数据,每次加载的代码都是一样的,可以大大节省内存。

(2)栈是由系统分配内存,栈的内存是固定的。

(3)堆区是程序员自己分配内存和释放内存,如果不释放内存,那么就只能等程序结束后才会由系统回收。内存不释放,那么在程序运行期间可能会导致内存不够用。

 

程序在没有运行前只有代码区和数据区,运行程序后会加载到内存中,才有堆区和栈区。

数据存储范围?

 1.栈区:栈区内存自动申请,不需要程序手动管理(我们说的分配内存其实是分配一个地址,内存其实是运行之后才会分配)

#include<stdio.h>

int* myFunc()
{
    int a = 10;//局部变量放在栈区,使用完后内存自动释放,所以不要返回局部变量的地址
    return &a;//数组名就是数组的首地址
}
char* getString()
{
    char str[] = "Hello World";
    return str;
}
void test01()
{
    int* p = myFunc();//myFunc中的a内存使用完后即被释放了,不会在test01中出现,所以打印不出值,会报错
    printf("*p=%d\n",*p);
}
void test02()
{
    char* s = NULL;
    s=getString();
    printf("s=%s\n",s);
}
int main()
{
    test01();
    test02();   
}

第一步:当执行getString方法中的代码时候

 

 第二步:getString方法执行完后,栈区中的数组str的内存就释放了,所以此时0x002这个地址就不存在了,当然就找不到值 hello World了。

输出结果

*p=10
s=烫烫烫烫烫烫狞?
请按任意键继续. . .

2.堆区:开辟堆空间 int * p= malloc(sizeof(int)*10);

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


void alloctateSpace(char * p)
{
    p = malloc(100);//分配100个字节的内存
    memset(p,0,100);//将这块内存中的值初始化为0值
    strcpy(p,"hello world!");
}


void test02()
{
    char* ret = NULL;
    alloctateSpace(ret);
    printf("ret=%s\n",ret);//ret=null
}

int main()
{
    test02();
    system("pause");
}

首先,执行allocateSpace方法完后,由于char * p是形参,所以执行完该方法后,p就被释放掉了

 

 

 

 所以最终ret的地址为NULL。

 

posted @ 2021-03-11 18:55  WellMandala  阅读(348)  评论(0编辑  收藏  举报