C语言malloc在函数内使用的问题

BrillianceRen 2010-08-10 09:24:27
假如我用malloc在一个函数内申请了一块堆,然后返回这个块的地址。
当这个函数结束的时候,这块堆空间会不会在程序运行的时候被再次使用?

malloc是给这块空间作了正在使用的标记
可是函数结束后会释放函数执行过程中产生的垃圾
虽然没有free,那么这块空间是否依然被标记正在使用?

例如
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char * create()
{
char *tmp;
tmp=(char *)malloc(100);
return tmp;
}
int main()
{
char *p;
p=create();
strcpy(p,"hello");
printf("%s\n",p);
free(p);
return 0;
}
...全文
1609 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
Jim_King_2000 2010-08-10
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 xy_zhang 的回复:]

引用 11 楼 yonghumingbuzhidao 的回复:

这就是传说中的野指针,访问了非法内存,是很危险的。可能现在不出错,但是等出了问题就死也找不到是这里啦,真是程序员的噩梦~
参考6楼,free后置NULL。
[/Quote]

strcpy也很危险。万一源字符串超过了100个字符,后果不堪设想。定位错误也很困难。所以,不要用strcpy,用strncpy。
walkersfaint 2010-08-10
  • 打赏
  • 举报
回复
野指针,内存泄露都很可怕的
xy_zhang 2010-08-10
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 yonghumingbuzhidao 的回复:]

C/C++ code

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char * create()
{
char *tmp;
tmp=(char *)malloc(100);
return tmp;
}
int main()
{
char *p;
p=create();
strcpy(p,"hello"……
[/Quote]

这就是传说中的野指针,访问了非法内存,是很危险的。可能现在不出错,但是等出了问题就死也找不到是这里啦,真是程序员的噩梦~
参考6楼,free后置NULL。
Jim_King_2000 2010-08-10
  • 打赏
  • 举报
回复
free(p)是把p所指向的内存释放。p依然可以再指向其它地方。但注意,free(p)之后,不能立即使用p所指向的内存,否则会引起undefined behavior。
Mike.Lee 2010-08-10
  • 打赏
  • 举报
回复

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char * create()
{
char *tmp;
tmp=(char *)malloc(100);
return tmp;
}
int main()
{
char *p;
p=create();
strcpy(p,"hello");
printf("%s\n",p);
free(p);
p="123";
printf("%s",p);
return 0;
}

在free(p),后,我又给P赋值了,且能正常执行,是何原因呢?
free(p),不是已经将内存释放了吗?为什么在执行free(p)后,p依然能使用呢?
jastdoit 2010-08-10
  • 打赏
  • 举报
回复
malloc申请的内存会一直存在,直到用free进行释放或程序结束(正常结束或异常结束)。
lyramilk 2010-08-10
  • 打赏
  • 举报
回复
你的代码是不会出现问题的。但是这种习惯不好。

“函数结束后会释放函数执行过程中产生的垃圾”这是错误的,C没有垃圾回收。
Jim_King_2000 2010-08-10
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 xy_zhang 的回复:]

这块空间可以正常使用,直到你free它。
就像你代码里写的那样,没有问题。

[/Quote]
不过程序结束之前,最好把它free掉。LZ可以google一下“内存泄漏”。
xy_zhang 2010-08-10
  • 打赏
  • 举报
回复
[Quote=引用楼主 ren0065 的回复:]
假如我用malloc在一个函数内申请了一块堆,然后返回这个块的地址。
当这个函数结束的时候,这块堆空间会不会在程序运行的时候被再次使用?

malloc是给这块空间作了正在使用的标记
可是函数结束后会释放函数执行过程中产生的垃圾
虽然没有free,那么这块空间是否依然被标记正在使用?

[/Quote]

这块空间可以正常使用,直到你free它。
就像你代码里写的那样,没有问题。
jiabin1223 2010-08-10
  • 打赏
  • 举报
回复
free后, 要赋空!free(p); p = NULL;

如果没赋空 p就会变成野指针! p的值是不会变的,仍然是一个地址值,仍然指向那块内存区,只是这块内存区的值变成垃圾了。
freshui 2010-08-10
  • 打赏
  • 举报
回复
堆和栈是不一样的, 堆有堆的管理,如果简单的说,可以理解为一个链表管理,管理已分配的和未分配的链表,每次malloc和free都会去维护这个链表。

栈是函数调用来管理的,编译的时候基本上就确定下来的:调用函数时,参数压栈,函数内的局部变量也压栈,函数调用完毕后,这些压栈的数据《必须》出栈,出栈后其占用的内存地址就供别人用了,这样也就是无论如何也不能返回栈内存地址的原因。
肥多罗 2010-08-10
  • 打赏
  • 举报
回复
存在但是不能用的 有冲突的可能
gaslinux 2010-08-10
  • 打赏
  • 举报
回复
malloc申请的内存会一直存在,直到用free进行释放或程序结束(正常结束或异常结束)。
ayw215 2010-08-10
  • 打赏
  • 举报
回复
new是在堆中分配的内存
函数的调用都是在栈上
二者不同
偶是江湖中人 2010-08-10
  • 打赏
  • 举报
回复
<高质量C/C++>书中有不能返回堆内存
函数在调用完后,会自动释放,返回堆内存,会出错,它的指向会没有内在空间
BrillianceRen 2010-08-10
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 jim_king_2000 的回复:]
修改指针参数需要指针的指针。
[/Quote]
哦。。。是哈。。。疏忽掉了= =!
yujixi123 2010-08-10
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 weicaijiang 的回复:]

<高质量C/C++>书中有不能返回堆内存
函数在调用完后,会自动释放,返回堆内存,会出错,它的指向会没有内在空间
[/Quote]堆跟栈是有区别的
Jim_King_2000 2010-08-10
  • 打赏
  • 举报
回复
修改指针参数需要指针的指针。
BrillianceRen 2010-08-10
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 weicaijiang 的回复:]
<高质量C/C++>书中有不能返回堆内存
函数在调用完后,会自动释放,返回堆内存,会出错,它的指向会没有内在空间
[/Quote]
堆内存不会释放,返回指针可以操作

[Quote=引用 2 楼 ayw215 的回复:]
new是在堆中分配的内存
函数的调用都是在栈上
二者不同
[/Quote]
我的意思是内存泄漏之类的问题,关于堆内存会不会被复用的问题。
系统标记了某块堆内存,函数的结束会不会影响这个标记?重复的分配堆空间会不会复用这块堆?

[Quote=引用 3 楼 gaslinux 的回复:]
malloc申请的内存会一直存在,直到用free进行释放或程序结束(正常结束或异常结束)。
[/Quote]
同上~~一直存在会不会被复用?

[Quote=引用 4 楼 wxflul 的回复:]
存在但是不能用的 有冲突的可能
[/Quote]
不明白什么意思= =!

[Quote=引用 5 楼 freshui 的回复:]
堆和栈是不一样的, 堆有堆的管理,如果简单的说,可以理解为一个链表管理,管理已分配的和未分配的链表,每次malloc和free都会去维护这个链表。
。。。
[/Quote]
乃也曲解我的意思了

[Quote=引用 6 楼 jiabin1223 的回复:]
free后, 要赋空!free(p); p = NULL;
如果没赋空 p就会变成野指针! p的值是不会变的,仍然是一个地址值,仍然指向那块内存区,只是这块内存区的值变成垃圾了。
[/Quote]
同上。。。

[Quote=引用 7 楼 xy_zhang 的回复:]
这块空间可以正常使用,直到你free它。
就像你代码里写的那样,没有问题。
[/Quote]
3Q,很感谢你肯定的回复,我会在看看高级c

[Quote=引用 9 楼 lyramilk 的回复:]
你的代码是不会出现问题的。但是这种习惯不好。

“函数结束后会释放函数执行过程中产生的垃圾”这是错误的,C没有垃圾回收。
[/Quote]
我的说法的确不对,随口而出,我所之的垃圾是函数内的临时栈变量~~~= =!

[Quote=引用 21 楼 kktemp234 的回复:]
在大多数UNIX实现中malloc会单独维护一个内存存,即当free后malloc并不会将内存归还给内核,而是自己保留,以便下次继续分配

函数中的内存在栈中分配,而malloc在堆中申请内存,另外一个函数(有些系统不支持)alloca可以在栈上分配内存,当函数调用结束后自动分配,但如果使用这个函数,会造成程序移植性问题。

由于不同的实现,malloc效率并不一样,尤其是当内存申请后,发……
[/Quote]
精彩回答~~~
内核标记了堆上的某段内存后,如果在函数中没有free,那么函数结束后会不会对这个标记产生影响呢?
我感觉似乎不会影响= =!希望我的猜测是正确的

[Quote=引用 30 楼 jim_king_2000 的回复:]
引用 26 楼 ren0065 的回复:

然后,假如我这样
C/C++ code

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void create(char *tmp)
{
tmp=(char *)malloc(100);
}
int main()
{
char *p;
create(p);
……
[/Quote]
我的第二个例子似乎没有那么严重的问题。。。。我正是传了一个指针作为参数阿= =!
Jim_King_2000 2010-08-10
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 ren0065 的回复:]

然后,假如我这样
C/C++ code

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void create(char *tmp)
{
tmp=(char *)malloc(100);
}
int main()
{
char *p;
create(p);
memcpy(p,"hello",6);
prin……
[/Quote]
疏忽了,你的程序有很严重的问题。


void create(char *tmp)
{
tmp=(char *)malloc(100);
}

这个tmp只是个局部变量,修改tmp不会引起实参的变化。因此最好用返回值来传出指针。


char *create(size_t size)
{
return (char *)malloc(size);
}


或者用指针的指针作为参数。


void create(char **tmp)
{
*tmp=(char *)malloc(100);
}

char *p;
create(&p);

加载更多回复(14)
1. C 语言中的指针和内存泄漏 5 2. C语言难点分析整理 10 3. C语言难点 18 4. C/C++实现冒泡排序算法 32 5. C++中指针和引用的区别 35 6. const char*, char const*, char*const的区别 36 7. C中可变参数函数实现 38 8. C程序内存中组成部分 41 9. C编程拾粹 42 10. C语言中实现数组的动态增长 44 11. C语言中的位运算 46 12. 浮点数的存储格式: 50 13. 位域 58 14. C语言函数二维数组传递方法 64 15. C语言复杂表达式的执行步骤 66 16. C语言字符串函数大全 68 17. C语言宏定义技巧 89 18. C语言实现动态数组 100 19. C语言笔试-运算符和表达式 104 20. C语言编程准则之稳定篇 107 21. C语言编程常见问题分析 108 22. C语言编程易犯毛病集合 112 23. C语言缺陷与陷阱(笔记) 119 24. C语言防止缓冲区溢出方法 126 25. C语言高效编程秘籍 128 26. C运算符优先级口诀 133 27. do/while(0)的妙用 134 28. exit()和return()的区别 140 29. exit子程序终止函数与return的差别 141 30. extern与static存储空间矛盾 145 31. PC-Lint与C\C++代码质量 147 32. spirntf函数使用大全 158 33. 二叉树的数据结构 167 34. 位运算应用口诀和实例 170 35. 内存对齐与ANSI C中struct内存布局 173 36. 冒泡和选择排序实现 180 37. 函数指针数组与返回数组指针的函数 186 38. 右左法则- 复杂指针解析 189 39. 回车和换行的区别 192 40. 堆和堆栈的区别 194 41. 堆和堆栈的区别 198 42. 如何写出专业的C头文件 202 43. 打造最快的Hash表 207 44. 指针与数组学习笔记 222 45. 数组不是指针 224 46. 标准C中字符串分割的方法 228 47. 汉诺塔源码 231 48. 洗牌算法 234 49. 深入理解C语言指针的奥秘 236 50. 游戏外挂的编写原理 254 51. 程序实例分析-为什么会陷入死循环 258 52. 空指针究竟指向了内存的哪个地方 260 53. 算术表达式的计算 265 54. 结构体对齐的具体含义 269 55. 连连看AI算法 274 56. 连连看寻路算法的思路 283 57. 重新认识:指向函数的指针 288 58. 链表的源码 291 59. 高质量的子程序 295 60. 高级C语言程序员测试必过的十六道最佳题目+答案详解 297 61. C语言常见错误 320 62. 超强的指针学习笔记 325 63. 程序员之路──关于代码风格 343 64. 指针、结构体、联合体的安全规范 346 65. C指针讲解 352 66. 关于指向指针的指针 368 67. C/C++ 误区一:void main() 373 68. C/C++ 误区二:fflush(stdin) 376 69. C/C++ 误区三:强制转换 malloc() 的返回值 380 70. C/C++ 误区四:char c = getchar(); 381 71. C/C++ 误区五:检查 new 的返回值 383 72. C 是 C++ 的子集吗? 384 73. C和C++的区别是什么? 387 74. 无条件循环 388 75. 产生随机数的方法 389 76. 顺序表及其操作 390 77. 单链表的实现及其操作 391 78. 双向链表 395 79. 程序员数据结构笔记 399 80. Hashtable和HashMap的区别 408 81. hash 表学习笔记 410 82. C程序设计常用算法源代码 412 83. C语言有头结点链表的经典实现 419 84. C语言惠通面试题 428 85. C语言常用宏定义 450

69,371

社区成员

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

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