5C语言内存分区
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了5C语言内存分区,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3229字,纯文字阅读大概需要5分钟。
内容图文
![5C语言内存分区](/upload/InfoBanner/zyjiaocheng/946/c152d32555f14964adb845b6382213e1.jpg)
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语言内存分区全部内容,希望文章能够帮你解决5C语言内存分区所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。