当这个函数结束的时候,这块堆空间会不会在程序运行的时候被再次使用?
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;
}
34 个解决方案
#1
<高质量C/C++>书中有不能返回堆内存
函数在调用完后,会自动释放,返回堆内存,会出错,它的指向会没有内在空间
函数在调用完后,会自动释放,返回堆内存,会出错,它的指向会没有内在空间
#2
new是在堆中分配的内存
函数的调用都是在栈上
二者不同
函数的调用都是在栈上
二者不同
#3
malloc申请的内存会一直存在,直到用free进行释放或程序结束(正常结束或异常结束)。
#4
存在但是不能用的 有冲突的可能
#5
堆和栈是不一样的, 堆有堆的管理,如果简单的说,可以理解为一个链表管理,管理已分配的和未分配的链表,每次malloc和free都会去维护这个链表。
栈是函数调用来管理的,编译的时候基本上就确定下来的:调用函数时,参数压栈,函数内的局部变量也压栈,函数调用完毕后,这些压栈的数据《必须》出栈,出栈后其占用的内存地址就供别人用了,这样也就是无论如何也不能返回栈内存地址的原因。
栈是函数调用来管理的,编译的时候基本上就确定下来的:调用函数时,参数压栈,函数内的局部变量也压栈,函数调用完毕后,这些压栈的数据《必须》出栈,出栈后其占用的内存地址就供别人用了,这样也就是无论如何也不能返回栈内存地址的原因。
#6
free后, 要赋空!free(p); p = NULL;
如果没赋空 p就会变成野指针! p的值是不会变的,仍然是一个地址值,仍然指向那块内存区,只是这块内存区的值变成垃圾了。
如果没赋空 p就会变成野指针! p的值是不会变的,仍然是一个地址值,仍然指向那块内存区,只是这块内存区的值变成垃圾了。
#7
这块空间可以正常使用,直到你free它。
就像你代码里写的那样,没有问题。
#8
不过程序结束之前,最好把它free掉。LZ可以google一下“内存泄漏”。
#9
你的代码是不会出现问题的。但是这种习惯不好。
“函数结束后会释放函数执行过程中产生的垃圾”这是错误的,C没有垃圾回收。
“函数结束后会释放函数执行过程中产生的垃圾”这是错误的,C没有垃圾回收。
#10
malloc申请的内存会一直存在,直到用free进行释放或程序结束(正常结束或异常结束)。
#11
#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依然能使用呢?
#12
free(p)是把p所指向的内存释放。p依然可以再指向其它地方。但注意,free(p)之后,不能立即使用p所指向的内存,否则会引起undefined behavior。
#13
这就是传说中的野指针,访问了非法内存,是很危险的。可能现在不出错,但是等出了问题就死也找不到是这里啦,真是程序员的噩梦~
参考6楼,free后置NULL。
#14
野指针,内存泄露都很可怕的
#15
strcpy也很危险。万一源字符串超过了100个字符,后果不堪设想。定位错误也很困难。所以,不要用strcpy,用strncpy。
#16
内存泄露会一点点榨干内存的..
#17
学习一下啊 没这么高水平
#18
C语言好像没有垃圾回收机制,要自己用free。
还有堆和栈有什么区别呢?
还有堆和栈有什么区别呢?
#19
strncpy要加那个头文件?我这里没法用
#20
在c中malloc和free应该是成对,组合出现的。
#21
在大多数UNIX实现中malloc会单独维护一个内存存,即当free后malloc并不会将内存归还给内核,而是自己保留,以便下次继续分配
函数中的内存在栈中分配,而malloc在堆中申请内存,另外一个函数(有些系统不支持)alloca可以在栈上分配内存,当函数调用结束后自动分配,但如果使用这个函数,会造成程序移植性问题。
由于不同的实现,malloc效率并不一样,尤其是当内存申请后,发现申请的内存不够大,需要更改时,这个时候已经不能局限于语言层面上讨论了
另外,一般的strcpy是不检测内存重叠的,但memcpy检测。
函数中的内存在栈中分配,而malloc在堆中申请内存,另外一个函数(有些系统不支持)alloca可以在栈上分配内存,当函数调用结束后自动分配,但如果使用这个函数,会造成程序移植性问题。
由于不同的实现,malloc效率并不一样,尤其是当内存申请后,发现申请的内存不够大,需要更改时,这个时候已经不能局限于语言层面上讨论了
另外,一般的strcpy是不检测内存重叠的,但memcpy检测。
#22
<string.h>这是标准库中定义的,不会没法用的。
#23
new是在堆中分配的内存
函数的调用都是在栈上
函数的调用都是在栈上
#24
现在先不讨论strcpy的问题,这个只是试验,我通常或用memcpy
我所说的函数结束后会不会被重复使用,不是说我返回了这个指针后能不能够用
而是说这块空间会不会被不可预料的修改,例如我在以后的程序里接连的使用malloc等分配内存的函数
这块在函数中分配的空间会不会被再次分配别的~~返回给某个新指针??
例如,我这个函数中返回的指针地址:100001指向这个块
以后我再次调用函数,是否会让另外的的指针指向这个块中的某个部分?破坏这个块中的数据?
我所说的函数结束后会不会被重复使用,不是说我返回了这个指针后能不能够用
而是说这块空间会不会被不可预料的修改,例如我在以后的程序里接连的使用malloc等分配内存的函数
这块在函数中分配的空间会不会被再次分配别的~~返回给某个新指针??
例如,我这个函数中返回的指针地址:100001指向这个块
以后我再次调用函数,是否会让另外的的指针指向这个块中的某个部分?破坏这个块中的数据?
#25
基本上,库函数是不会破坏你的数据的。也不会把已分配的空间再次分配。除非我们自己写越界了。
#26
然后,假如我这样
这样的话,跟最初的代码有没有区别?分配的空间有没有被复用的危险?
#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);
printf("%s\n",p);
free(p);
p=NULL;
return 0;
}
这样的话,跟最初的代码有没有区别?分配的空间有没有被复用的危险?
#27
= =!似乎这两种方式都一样。。。。。NC了我
#28
为什么是基本上??
有可能会破坏数据吗?
#29
越界就会破坏数据。LZ可以google一下“缓冲区溢出攻击”。
#30
疏忽了,你的程序有很严重的问题。
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);
#31
堆内存不会释放,返回指针可以操作
我的意思是内存泄漏之类的问题,关于堆内存会不会被复用的问题。
系统标记了某块堆内存,函数的结束会不会影响这个标记?重复的分配堆空间会不会复用这块堆?
同上~~一直存在会不会被复用?
不明白什么意思= =!
乃也曲解我的意思了
同上。。。
3Q,很感谢你肯定的回复,我会在看看高级c
我的说法的确不对,随口而出,我所之的垃圾是函数内的临时栈变量~~~= =!
精彩回答~~~
内核标记了堆上的某段内存后,如果在函数中没有free,那么函数结束后会不会对这个标记产生影响呢?
我感觉似乎不会影响= =!希望我的猜测是正确的
我的第二个例子似乎没有那么严重的问题。。。。我正是传了一个指针作为参数阿= =!
#32
修改指针参数需要指针的指针。
#33
堆跟栈是有区别的
#34
哦。。。是哈。。。疏忽掉了= =!
#1
<高质量C/C++>书中有不能返回堆内存
函数在调用完后,会自动释放,返回堆内存,会出错,它的指向会没有内在空间
函数在调用完后,会自动释放,返回堆内存,会出错,它的指向会没有内在空间
#2
new是在堆中分配的内存
函数的调用都是在栈上
二者不同
函数的调用都是在栈上
二者不同
#3
malloc申请的内存会一直存在,直到用free进行释放或程序结束(正常结束或异常结束)。
#4
存在但是不能用的 有冲突的可能
#5
堆和栈是不一样的, 堆有堆的管理,如果简单的说,可以理解为一个链表管理,管理已分配的和未分配的链表,每次malloc和free都会去维护这个链表。
栈是函数调用来管理的,编译的时候基本上就确定下来的:调用函数时,参数压栈,函数内的局部变量也压栈,函数调用完毕后,这些压栈的数据《必须》出栈,出栈后其占用的内存地址就供别人用了,这样也就是无论如何也不能返回栈内存地址的原因。
栈是函数调用来管理的,编译的时候基本上就确定下来的:调用函数时,参数压栈,函数内的局部变量也压栈,函数调用完毕后,这些压栈的数据《必须》出栈,出栈后其占用的内存地址就供别人用了,这样也就是无论如何也不能返回栈内存地址的原因。
#6
free后, 要赋空!free(p); p = NULL;
如果没赋空 p就会变成野指针! p的值是不会变的,仍然是一个地址值,仍然指向那块内存区,只是这块内存区的值变成垃圾了。
如果没赋空 p就会变成野指针! p的值是不会变的,仍然是一个地址值,仍然指向那块内存区,只是这块内存区的值变成垃圾了。
#7
这块空间可以正常使用,直到你free它。
就像你代码里写的那样,没有问题。
#8
不过程序结束之前,最好把它free掉。LZ可以google一下“内存泄漏”。
#9
你的代码是不会出现问题的。但是这种习惯不好。
“函数结束后会释放函数执行过程中产生的垃圾”这是错误的,C没有垃圾回收。
“函数结束后会释放函数执行过程中产生的垃圾”这是错误的,C没有垃圾回收。
#10
malloc申请的内存会一直存在,直到用free进行释放或程序结束(正常结束或异常结束)。
#11
#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依然能使用呢?
#12
free(p)是把p所指向的内存释放。p依然可以再指向其它地方。但注意,free(p)之后,不能立即使用p所指向的内存,否则会引起undefined behavior。
#13
这就是传说中的野指针,访问了非法内存,是很危险的。可能现在不出错,但是等出了问题就死也找不到是这里啦,真是程序员的噩梦~
参考6楼,free后置NULL。
#14
野指针,内存泄露都很可怕的
#15
strcpy也很危险。万一源字符串超过了100个字符,后果不堪设想。定位错误也很困难。所以,不要用strcpy,用strncpy。
#16
内存泄露会一点点榨干内存的..
#17
学习一下啊 没这么高水平
#18
C语言好像没有垃圾回收机制,要自己用free。
还有堆和栈有什么区别呢?
还有堆和栈有什么区别呢?
#19
strncpy要加那个头文件?我这里没法用
#20
在c中malloc和free应该是成对,组合出现的。
#21
在大多数UNIX实现中malloc会单独维护一个内存存,即当free后malloc并不会将内存归还给内核,而是自己保留,以便下次继续分配
函数中的内存在栈中分配,而malloc在堆中申请内存,另外一个函数(有些系统不支持)alloca可以在栈上分配内存,当函数调用结束后自动分配,但如果使用这个函数,会造成程序移植性问题。
由于不同的实现,malloc效率并不一样,尤其是当内存申请后,发现申请的内存不够大,需要更改时,这个时候已经不能局限于语言层面上讨论了
另外,一般的strcpy是不检测内存重叠的,但memcpy检测。
函数中的内存在栈中分配,而malloc在堆中申请内存,另外一个函数(有些系统不支持)alloca可以在栈上分配内存,当函数调用结束后自动分配,但如果使用这个函数,会造成程序移植性问题。
由于不同的实现,malloc效率并不一样,尤其是当内存申请后,发现申请的内存不够大,需要更改时,这个时候已经不能局限于语言层面上讨论了
另外,一般的strcpy是不检测内存重叠的,但memcpy检测。
#22
<string.h>这是标准库中定义的,不会没法用的。
#23
new是在堆中分配的内存
函数的调用都是在栈上
函数的调用都是在栈上
#24
现在先不讨论strcpy的问题,这个只是试验,我通常或用memcpy
我所说的函数结束后会不会被重复使用,不是说我返回了这个指针后能不能够用
而是说这块空间会不会被不可预料的修改,例如我在以后的程序里接连的使用malloc等分配内存的函数
这块在函数中分配的空间会不会被再次分配别的~~返回给某个新指针??
例如,我这个函数中返回的指针地址:100001指向这个块
以后我再次调用函数,是否会让另外的的指针指向这个块中的某个部分?破坏这个块中的数据?
我所说的函数结束后会不会被重复使用,不是说我返回了这个指针后能不能够用
而是说这块空间会不会被不可预料的修改,例如我在以后的程序里接连的使用malloc等分配内存的函数
这块在函数中分配的空间会不会被再次分配别的~~返回给某个新指针??
例如,我这个函数中返回的指针地址:100001指向这个块
以后我再次调用函数,是否会让另外的的指针指向这个块中的某个部分?破坏这个块中的数据?
#25
基本上,库函数是不会破坏你的数据的。也不会把已分配的空间再次分配。除非我们自己写越界了。
#26
然后,假如我这样
这样的话,跟最初的代码有没有区别?分配的空间有没有被复用的危险?
#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);
printf("%s\n",p);
free(p);
p=NULL;
return 0;
}
这样的话,跟最初的代码有没有区别?分配的空间有没有被复用的危险?
#27
= =!似乎这两种方式都一样。。。。。NC了我
#28
为什么是基本上??
有可能会破坏数据吗?
#29
越界就会破坏数据。LZ可以google一下“缓冲区溢出攻击”。
#30
疏忽了,你的程序有很严重的问题。
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);
#31
堆内存不会释放,返回指针可以操作
我的意思是内存泄漏之类的问题,关于堆内存会不会被复用的问题。
系统标记了某块堆内存,函数的结束会不会影响这个标记?重复的分配堆空间会不会复用这块堆?
同上~~一直存在会不会被复用?
不明白什么意思= =!
乃也曲解我的意思了
同上。。。
3Q,很感谢你肯定的回复,我会在看看高级c
我的说法的确不对,随口而出,我所之的垃圾是函数内的临时栈变量~~~= =!
精彩回答~~~
内核标记了堆上的某段内存后,如果在函数中没有free,那么函数结束后会不会对这个标记产生影响呢?
我感觉似乎不会影响= =!希望我的猜测是正确的
我的第二个例子似乎没有那么严重的问题。。。。我正是传了一个指针作为参数阿= =!
#32
修改指针参数需要指针的指针。
#33
堆跟栈是有区别的
#34
哦。。。是哈。。。疏忽掉了= =!