静态存储区、栈、堆、常量修改等等得瑟

内容非原创,但也绝不是转载,实在选不好分类,索性就原创了,惭愧惭愧。闲话少说,进入正题。

昨天在做个试题时遇到了个问题,自己写了个strcat函数,在测试过程中出现了错误,很让我诧异啊,感觉自己写代码还凑合,哎,看来真的是啥也不是啊


调了半天没找到原因,先上个代码吧

*
* Func: my_str_append
* IN,OUT:  *dest  目标字符串
* IN:  *sour       源字符串          
* DES:            将sour中的字符串添加到dest尾部
*/
char* my_str_append(char* dest,char* sour)
{
	char* cp = dest;
	while(*cp)
		cp++;
	while(*cp++ = *sour++); //执行到这个位置就要出错
	return dest;
}
int main()
{
   char *ptr = my_str_append("aaa","bbb");
   return 0 
}
同学提看了下提示是字符串常量的问题。改了一下,果然,自己太菜了,顺便感谢下提醒我的同学。

那么现在就要回顾下内存分配的一些知识了,学习c/c++,对内存分配不清楚,也挺悲剧的。

可编程内存可以分为:静态存储区、堆区和栈区。

静态存储区:主要用来存放全局变量、静态变量以及常量。静态存储区在整个程序的生命周期内都在。

栈区:栈是根据函数的调用动态分配与回收,它的操作由系统完成,有个概念叫栈帧,就是指的每个函数自己的局部空间。函数内创建的局部变量均存储在属于它自己的栈帧中

堆区:堆属于动态分配的存储空间,通过malloc,new等函数进行分配,成功分配的内存只有在主程序退出或调用free或delete函数才能释放,因此,可以说堆区的存储空间给了我们很大的可控性,当然,过份的自由自然会带来问题。这种情况下,内存泄露极易发生。良好的习惯是啥呢,对了D说的对,谁开发,谁治理。不用了,就释放掉,不要等着程序结束靠系统来搞这些。

用途就说这么多了,在来看看,这个和我遇到的问题有啥关系。

首先看第一个参数”aaa“,没错,它是字符串常量,字符串常量存储在静态数据区,在my_str_append中,我们的目的是在aaa后面添加bbb,由于指针是指向常量aaa的首地址,不管你是直接修改常量,还是在尾部添加,都是错误的(当然有些手段可以改变常量的值)。

于是,问题就来了,那怎么改呢?没错,可以考虑创建一个空间够大的数组,将字符串常量赋值到数组中,这样就可以操作了。

另外,通过new一个指针来,将常量字符串赋值到指针所指的空间也可以。当然,new一个指针,直接对该指针赋值是不行的,这样相当于又指向常量的位置了。


写到这里,其实我不断的在问自己,赋值到数组中就可以操作了,那么造成无法修改的原因到底是什么?是因为是常量?是因为不在栈区?在栈区就可以了修改了?

其实我的这种提问有大的逻辑问题。一个关键点,常量不在栈区。所以核心问题是,存储的位置不在栈区,ok,但是全局变量也不在栈区啊,静态变量也不在栈区啊。这里面应该就涉及到常量的具体实现上了。或者说,静态存储区又有更加细致的区分。小弟不才,暂时还没有深入理解。此贴留着,慢慢完善,有兄弟,愿意讲讲更好了,谢谢


昨天坐车的时候翻了翻高质量c++程序指南,讲的真挺好的,要抓紧时间看看了,有些内容要以专题的形式回顾,当然从我的水平来看,应该算是学习吧

为了记录自己成长的过程,前面写的有错的地方我也不准备删了,继续跟进。

现在在看看自己写的文章,思路确实有点乱,以后改进。对于昨天的问题,其实就是一点,先抛开存在什么位置不说,修改常量是不允许的,出错是肯定的了。常量是存放在静态存储区,静态存储区与变量是否可以修改没有任何联系。就这个意思,清楚了。

至于为什么通过数组就可以修改了,原因不在于数组是在什么地方创建(栈,堆,静态存储),而是因为将常量字符串复制到了具有足够空间的数据组中,因为数组没有定义成常量数组,所以数组的内容自然就可以修改了。

好好看书,加油了!发火










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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值