C语言-1.3内存是的分区

1、首先看一下经典存储空间安排(来自环境高级编程P164页)

             __________________________
高地址 |                                                    | 命令行参数和环境变量
            |__________________________

            |                     栈                           | 栈空间,往下生长
            | ...................................................|

            |                                                    |
            |___________堆_______  _____| 
            |                                                    |
            |__________________________| 未初始化数据段
            |                                                    |
            |__________________________| 初始化数据段
            |                                                    |
低地址 |__________________________| 代码段

(1)正文段是由cpu执行的机器指令部分,是共享区,是只读权限;

(2)bss段:定义的全局变量;默认赋值0;

(3)初始化数据段:例如数据常量,字符常量,静态变量

(4)堆一般用于动态分配内存,位于bss和栈之间;

(5)栈,局部变量,以及每次函数所需保存的信息都放在此段;

在linux中我们通过size /user/bin/cc /bin/shc 查看每个段的大小

栈区分析(记住函数返回的是一个地址值还是返回一个立即数?!?)

如果是返回一个int 整数,这个整数应该放在哪里?地址呢?
1、下面哪种写法是错误的?

char *getstr()
{
char *p="12334";  //请问p属于一个变量,而且是在栈区分配的空间,执行完就释放了,为什么还能返回主函数呢????

printf("%#d\n",p);此处打印的p和主函数打印的q的值相等吗???
return *p;
}
char *getstr2()
{
char p[]="1234";
return p;
}

int sum()
{
    int num=100;//num也是一个局部变量,函数执行完就释放了;为什么可以返回栈空间的值呢??
    return num;
}

char sum2()
{
    int num=999;//如果返回的类型装不下局部空间的值,会发生什么情况呢??
    return num;
}

int main()

{

char *q;

q=getstr();

printf("%s %#x\n",q,q);

return 0;

}

2、为什么p、q打印的值是一样的
char *p="1234";
char *q="1234";
printf("%#x, %#x",p, q);  打印的值是一样的;

3、下面程序输出什么??为什么是乱码
永远不要从函数中返回局部自动变量的地址
不能返回函数中定义的指针??
但是可以返回函数中定义的变量??

char *get_str()
{
char str[]="123456";
return str;
}
int main
{
char buf[128]={0};
strcpy(buf, get_str());
printf("%s\n",buf);
return 0;
}

堆区分析
1、如何改造才能使用呢?什么时候能返回指针??

char *get_str()
{
char *str=(char *)malloc(100*sizeof(char));//该怎么释放呢
if(str==NULL) exit(-1);
return str;
}
int main
{
char buf[128]={0};
strcpy(buf, get_str());
printf("%s\n",buf);
return 0;
}

 

 

在C语言编程中,我们经常会遇到这种情况,在某个函数中经过算法处理以后得到一个字符串类型的结果,可能需要将这个字符串以指针的形式进行返回,那么如何在函数中正确返回该字符串的内容呢?
例如,定义一个函数,要求该函数能够返回一个指向字符串“I love C.”的指针并能在主程序中正确得到该字符串的内容。对于初学者来说,当看到这个题目时,感觉并不难做到,可能很容易的写出下面形式的代码

char *getstr2()
{
char p[]="1234";
return p;
}
代码中定义了一个函数getString1,其目的是返回“I love C.”字符串。该函数返回值是char类型的指针,在函数内部定义了一个char类型包括20个元素的数组str并赋值为“I love C.”,然后返回数组的名称str,即字符串的地址。
乍一看,该函数写的没问题,似乎在主程序中调用该函数能得到正确的字符串内容“I love C.”,但实际上,这种方式并不能达到我们的目的。
其原因是,在函数内部定义的str数组是一个局部变量,将“I love C.”字符串存放在里面,当函数调用结束时,局部变量的内容将被操作系统自动收回,所以在主程序调用时,随着函数getString1调用的结束,其内部的str数组也就不存在了,自然也就不能将它里面20个元素的内容返回到主程序中了。
函数中返回字符串指针的正确方法
那么,如何在函数中正确返回字符串的内容呢?实际上,我们只要对上面的函数作一下修改,如下图所示就可以了:

char *getstr()
{
char *p="12334";
return *p;
}
该函数getString2同上面的getString1的区别是,在函数内部定义了一个指向char类型的指针p,该指针指向一个字符串常量“I love C.”,我们知道,这个字符串“I love C.”存放在整个程序的常量区,而并不是getString2的局部变量,也就是说,在程序整个的运行周期内,该字符串“I love C.”常量始终存在,并不会因为函数调用的结束而消失。
所以,指针变量p虽然是一个局部变量,但p本身的值仅仅是一个4个字节的指针地址值,这个地址值也就是“I love C.”的字符串的地址值。当函数调用结束时,虽然p局部变量不存在了,但可以将这个地址(仅4个字节)返回到主程序中,在主程序中通过这个地址值,我们是可以得到这个字符串“I love C.”的。
对比一下,字符串“I love C.”在getString1函数中存储在局部变量区,而在getString2函数中存储在整个程序的常量区,所以在getString2函数中将该常量区的地址返回,在主程序可以通过该地址得到这个字符串的内容;

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LuckyDog0623

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值