c语言中,系统申请的内存空间不自动释放会出问题吗?

mizaru 2017-09-06 08:31:55
1. 字符串变量所占的内存块数据不会被自动释放:
在c语言中,定义一个 char* c=“abc”,然后有让c=“efg”,这个过程,实际上是让系统开辟一个值为abc的内存块,让c指向之,然后又开辟一个值为efg的内存块,让c重新指向之。。但之前那个值为abc的内存区域,其数据没有被清空。。(稍后我会实验 验证一下)

2.函数结束后,函数内定义的变量,其所占内存不会被释放。
如果我有一个 test 函数,里面有个 局部变量 i ,我们在main中调用 test ,你会发现 test 的调用结束后,i 所占的内存空间依然有数据。
详情可观此实验:

int* testMemFreeInt();
#include <stdio.h>
int main()
{char* c="abc"; //c指向支付串 1234
int* pointer_i;
printf("c adress %d \n", c ); // 输出 c 的地址 ,我电脑中为4199239
c="efg"; //让c重新指向另一个 字符串
printf("c new adress %d \n",c); //再次输出c的地址,你会发现c的地址成立4199258

/*以上地址都是我电脑里的,请要测试的朋友执行根据自己电脑改地址*/

printf("c old adress value is %s \n",(char*)4199239);
/*但从原来的地址中取值,发现旧地址中的内容还没清空*/

pointer_i=testMemFreeInt();
//pointer_i指向的是testMemFreeInt里的变量i的地址

printf("i old adress value is %d \n",*pointer_i);
/* 尽管函数已结束,但函数中定义的变量i所占用的内存没有被释放,里面还有值*/
return 0;
}

int* testMemFreeInt()
{int i=123;
printf("i adress %d \n", &i);
return &i; //函数结束后,将i的地址返回去处
}


...全文
876 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2017-09-06
  • 打赏
  • 举报
回复
其实电脑开机后物理内存的每个字节中都有值且都是可读写的,从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页,一页通常为4KB。 栈中的变量通常包括函数参数和函数里声明的临时变量。 栈中的基本变量退出其作用域时,没有谁执行一段代码去释放/销毁/析构它所占用的内存,仅仅是没人再去理会的留在当前栈顶上方的若干遗留下来可被后续压栈操作覆盖的无用数据而已。 而栈中的类变量退出其作用域时,会自动执行其析构函数,……
  • 打赏
  • 举报
回复
2楼说的对,释放和清空是两种概念。 函数返回时,i的内容并没有改变,即i所指的地址没变。 传回去之后 pointer_i所指的地址与原i所指的地址没变。 因为本程序很简单,所以 pointer_i所指地址内的内容应该也没有改变。不过编译系统 会不会重新布置内存空间就不一定了。如果程序复杂 一点就不好说了。反正这是一个明显的“野指针”,这片内存区已经不属于你可控的了,编译器很可能下一次把这片内存区覆盖掉,自己编程是要杜绝此类情况的发生。
paschen 2017-09-06
  • 打赏
  • 举报
回复
这些是常量字符串是存在常量区,不在堆上,不需要清除,生成的EXE文件中本身就包含了这些常量,程序运行后将会加载到内存,整个程序运行过程中都会存在
老马何以识途 2017-09-06
  • 打赏
  • 举报
回复
内存释放和清空不是同一个概念,实际上释放并不需要清空,只需要把这一块内存挂到空闲内存块链表中,就完成释放了,但这块内存中的值并没有变化,直到重新被分配并赋值。 如果你在函数结束时把一个局部变量的地址返回,很可能可以得到一个正确的结果,但也不一定,如果这块内存被其他函数使用了,它的值就会变化。我们让函数返回一个值,一般都是在调用处马上把返回值赋给另一个变量,语句执行完对该局部变量的引用也结束了,我们再引用该返回值,实际上是调用处的那块内存,所以是没有问题的。
自信男孩 2017-09-06
  • 打赏
  • 举报
回复
"abc"和"efg"都是只读数据,在只读数据区存放。指针变量c是一个变量,它存放的是这两个字符串中一个的地址(同一时间只能存放一个字符串的地址)。这两个字符串在只读数据段的不同位置,所以当变量c指向"efg"时,并不是"efg"覆盖了"abc",所以c存放的地址值也是不一样的。
mk_lucifer 2017-09-06
  • 打赏
  • 举报
回复
其实不是这样的,字符串和其他常数都是代码段,连全局变量都不是,没有开辟过内存,是直接跟着代码按照导入规则从文件复制过去的,所有常数都这样。。 给你举个例子,甚至会出现类似的代码 0001 ADD XXX,XXX 0003 J 0004 0002 abc 0004 MOV R1,002H a这就是常数,他的地址就在代码里了,这东西本身就是程序代码,程序代码有没有内存,当然有,但是你从来没申请过他,在你导入进程时就存在。

70,005

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧