码迷,mamicode.com
首页 > 编程语言 > 详细

5C语言内存分区

时间:2019-11-24 22:46:22      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:turn   定义   用户   开始   报错   调用   png   结束   c语言   

技术图片
1)代码区:可执行程序代码存放区,这个我们不用关心;
2)全局区:
1全局与静态变量区:存放全局变量与静态变量,又可以区分为已经初始化的全局变量和静态变量区以及为初始化的全局变量和静态变量区;
2常量区:字符串常量与const修饰的常量存放在常量区;

3)堆区:用户动态申请的内存区,需要用户进行释放,否则有可能会造成内存泄漏;
4)栈区:该区内存由系统自动分配和释放,存放局部变量以函数实参等。
1全局区分析
看一段代码:

char *get_str()
{
    char *p="abcd";//文字常量区
    return p;
}
char *get_str1()
{
    char *q="abcd";//文字常量区
    return q;
}
int main()
{
    char *p=NULL;
    char *q=NULL;
    p=get_str();
    q=get_str1();
    //%s,打印指针指向内存区域的内容
    //%d打印p本身的值
    printf("p=%s,p=%d\n",p,p);
    printf("q=%s,q=%d\n",q,q);

    return 0;
}

运行结果:
技术图片
原因:
技术图片
看图,从主函数main开始,在栈区定义了两个指针变量p、q为空,占4个字节;
下面调用get_str();函数返回地址,在get_str();函数中又定义了一个p这个p给主函数中的p目前没有关系,在get_str();函数中把字符串abcd赋值给p,而abcd是在文字常量区定义的,假如地址为oxaabb,只有程序结束,才会被释放。
有get_str();返回的是地址oxaabb给主函数中的p,指针指向谁,就把谁的地址赋给谁,所以当get_str();释放后,主函数的p已经指向了文字常量区的abcd,同样的原理,由于get_str1()也是把相同的字符串abcd赋值给
q,q也是指向文字常量区的0xaabb,所以他们两个地址是相同的,当然如是在赋值的字符串不同,那地址一定不同。
赋值字符串不同时:

char *get_str()
{
    char *p="abcd1";//文字常量区
    return p;
}
char *get_str1()
{
    char *q="abcd2";//文字常量区
    return q;
}
int main()
{
    char *p=NULL;
    char *q=NULL;
    p=get_str();
    q=get_str1();
    //%s,打印指针指向内存区域的内容
    //%d打印p本身的值
    printf("p=%s,p=%d\n",p,p);
    printf("q=%s,q=%d\n",q,q);

    return 0;
}

运行结果:

技术图片
2栈区分析
技术图片

char *get_str2()
{
    char str[]="abcd";
    printf("str=%s\n",str);
    return str;//返回str数组的地址
}
int main()
{
    char buf[100]={0};
    strcpy(buf,get_str2());
printf("buf = %s\n",buf);

    return 0;
}

运行出错。

char *get_str2()
{
    char str[]="abcd";
    printf("str=%s\n",str);

    return str;//返回str数组的地址
}
int main()
{
    //char buf[100]={0};
    //strcpy(buf,get_str2());
    char *p=NULL;
    p=get_str2();

   // printf("buf = %s\n",buf);
    printf("p= %s\n",p);

    return 0;
}

运行结果:
技术图片
为什么p为空那?
技术图片
看图,有于get_str2()函数调用完被释放,str空间被回收,str空间的内容就未知,p指向就没有了,p没有指向会报错或乱码或为NULL。注意这里的char str[]="abcd";是赋值,并不是指针的指向。
3堆区分析

char *get_str3()
{
    //堆区手动分配空间
    char *str=(char *)malloc(sizeof (char)*100);
    if(str==NULL)//分配失败
    {
        return NULL;//返回空
    }
    //分配成功
    strcpy(str,"abcd");
    return str;//返回地址
}
int main()
{
    //char buf[100]={0};
    //strcpy(buf,get_str2());
    char *p=NULL;
    p=get_str3();
    if(p!=NULL)//p不为空
    {
        printf("p= %s\n",p);//打印
        free(p);//手动释放
        p=NULL;//赋值为空
    }
   // printf("buf = %s\n",buf);
    return 0;
}

运行结果:
技术图片
技术图片
4函数调用模型
技术图片
注:main函数在栈区开辟的内存,所有子函数都可以使用
main函数在堆区开辟的内存,所有子函数都可以使用
子函数开辟的栈区内存,只有其内部子函数才能使用
子函数在堆区开辟的内存,主函数与子函数内部的子函数都可以使用
子函数在全局区开辟的内存,主函数与子函数内部的子函数都可以使用

5栈的生长方向和内存存放的方向

int main()
{
    int a;
    int b;
    printf("&a=%d,&a=%d\n",&a,&b);//栈区生长方向是向下的

    char *p=(char *)malloc(10);
    char *q=(char *)malloc(10);
    printf("p=%d,q=%d\n",p,q); //堆区生长方向是向上的

    int buf[4];
    printf("&buf[0]=%d,&buf[1]=%d\n",&buf[0],&buf[1]); //数组生长方向是向上的
    return 0;
}

运行结果:
技术图片

5C语言内存分区

标签:turn   定义   用户   开始   报错   调用   png   结束   c语言   

原文地址:https://blog.51cto.com/14165014/2453102

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!