C语言内存使用小结

对于内存我们一般将其进行以下的方式来划分
这里写图片描述

细分各区

text(代码区):函数 只读
data(数据区):
1、【可读可写】 初始化的全局变量,初始化的static变量
2、【只读】 文字常量区,字符串常量
bss:
【可读可写】 没有初始化的全局变量,没初始化的static变量
stack(栈区):【可读可写】普通非static局部变量,函数形参,const修饰的非全局变量
heap(堆区) 【可读可写】 用户手动申请,手动关闭

1、文字常量区的小结
注:以下的示例代码均为错误示例并且所画图中的地址均是个人乱起的地址,仅仅是方便更好表达
示例代码
char *func()
{
    char *p = "hello";
    return p;
}

int main()
{
    char *s = func();
    s[1] = 'x';
    return 0;
}

这里写图片描述
因为”hello”位于文字常量区,所以当func()调用结束时不会随之释放,所以s有效的指向了该片空间;然而由于文字常量区是只读的,所以示例代码中的s[i] = ‘x’;是错误的

2、栈区的小结
示例代码
char *func()
{
    char p1[] = "world";
    char *p = "hello";
    return p1;
}

int main()
{
    char *ps;
    ps = func();
    printf("%s\n", p);
    return 0;
}

这里写图片描述
函数func()返回的是数组p1在栈区中的首元素地址,由于当func()结束时,其作用域内的变量在栈区中的内存也随之释放了,此时主函数中的p无法接收到地址0xabc

3、堆区中的小结
示例代码

“`
void func1(char *tmp)
{
tmp = (char *)malloc(strlen(“hello”) + 1);
}
char *func2()
{
char p = (char )malloc(strlen(“hello”) + 1);
return p;
}

int main()
{
char *q1 = NULL;
func1(q1);
char *q2 = func2();
strcpy(q1, “hello”);
strcpy(q2, “hello”);

}
这里写图片描述“`

func1()中,当其被调用完时,tmp空间自动释放,但其所指向的堆空间不释放,q1还是NULL,则对q1指向的空间进行内容拷贝会出现段错误
func2()中,由于q2与p共同指向了同一片堆空间,p释放后并不会影响q2的指向与堆空间,所以可以对q2指向的空间进行内容拷贝

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值