释放函数内部的指针,并在 main 中使用它
Freeing a pointer inside a function, and using it in main
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
char* test() {
char* s = "Hello World";
size_t len = strlen(s);
char* t = malloc(sizeof(char)*(len+1));
strcpy(t, s);
free(t);
return t;
};
int main(void) {
printf("%s\n", test());
return 0;
};
我想在函数内部分配和取消分配内存。我测试了这段代码并且有效,但我想知道:
- 为什么这样做有效?
- 在
main
中使用已释放指针的值是好习惯吗?
一旦你在一个指针上调用free
,它指向的内存就不再有效。尝试使用指向已释放内存的指针会触发 undefined behavior。在这个 特殊的 案例中,它碰巧起作用了,但不能保证。
如果函数 returns 分配了内存,调用者有责任释放它:
char* test() {
char* s = "Hello World";
size_t len = strlen(s);
char* t = malloc(sizeof(char)*(len+1));
strcpy(t, s);
return t;
};
int main(void) {
char *t = test();
printf("%s\n", t);
free(t);
return 0;
};
malloc
保留内存以供使用。
free
释放该保留。通常,它不会使内存消失,不会更改该内存的内容,也不会更改保存地址的指针的值。
在 free(t)
之后,t
的字节仍然包含与 free
之前相同的位设置。然后 return t;
return 将这些位发送给调用者。
当 main
将这些位传递给 printf
时,printf
将它们用作地址以获取 %s
的字符。由于没有任何改变,它们被打印出来。
这就是为什么你得到了你对这个程序所做的行为。但是,none 是有保证的。一旦用 t
调用 free
,内存预留就消失了。您程序中的其他东西可能使用了该内存。例如,printf
可能已经为其内部使用分配了一个缓冲区,并且可能使用了相同的内存。
在大多数情况下,malloc
和 free
只是协调使用内存的方法,这样您的程序的不同部分就不会尝试同时使用同一内存不同的目的。当您的程序只有一部分使用分配的内存时,程序的其他部分不会干扰它。所以缺乏协调并没有导致你的程序失败。如果您的程序中有多个例程使用分配的内存,那么在释放内存后尝试使用内存更有可能遇到问题。
此外,一旦内存被释放,编译器可能会将指向它的指针视为没有固定值。 return t;
语句不需要 return 任何特定值。
您 free()
指向何处并不重要。一旦它是 free()
d,指针就不再是可延迟的(既不在函数内部也不在函数外部,它是 free()
d)
free()
的目的是 return 用 malloc()
分配的内存,所以语义是,一旦你释放了一块内存,它就不再可用了。
在C中,所有参数都是按值传递的,所以free()
不能改变你传递给它的值表达式,这就是指针不会变成无效指针值的原因(比如NULL
) 但建议您在不引发未定义行为的情况下不能再使用指针。
在free()
的设计中可以有一个解决方案,就是把保存指针的指针变量按地址传递,这样free()
就可以把指针变成一个NULL
。但这不仅需要做更多的工作,而且 free()
不知道你对 malloc()
给你的价值做了多少份......所以不可能知道你有多少引用有在那里作废。这种方法不可能赋予 free()
使对 returned 内存的引用无效的责任。
所以,如果你认为 free 不会将指针变成 NULL
并且出于某些奇怪的原因你仍然可以使用内存 returned,请不要再这样做了,因为你会犯错的。
建议您! :)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
char* test() {
char* s = "Hello World";
size_t len = strlen(s);
char* t = malloc(sizeof(char)*(len+1));
strcpy(t, s);
free(t);
return t;
};
int main(void) {
printf("%s\n", test());
return 0;
};
我想在函数内部分配和取消分配内存。我测试了这段代码并且有效,但我想知道:
- 为什么这样做有效?
- 在
main
中使用已释放指针的值是好习惯吗?
一旦你在一个指针上调用free
,它指向的内存就不再有效。尝试使用指向已释放内存的指针会触发 undefined behavior。在这个 特殊的 案例中,它碰巧起作用了,但不能保证。
如果函数 returns 分配了内存,调用者有责任释放它:
char* test() {
char* s = "Hello World";
size_t len = strlen(s);
char* t = malloc(sizeof(char)*(len+1));
strcpy(t, s);
return t;
};
int main(void) {
char *t = test();
printf("%s\n", t);
free(t);
return 0;
};
malloc
保留内存以供使用。
free
释放该保留。通常,它不会使内存消失,不会更改该内存的内容,也不会更改保存地址的指针的值。
在 free(t)
之后,t
的字节仍然包含与 free
之前相同的位设置。然后 return t;
return 将这些位发送给调用者。
当 main
将这些位传递给 printf
时,printf
将它们用作地址以获取 %s
的字符。由于没有任何改变,它们被打印出来。
这就是为什么你得到了你对这个程序所做的行为。但是,none 是有保证的。一旦用 t
调用 free
,内存预留就消失了。您程序中的其他东西可能使用了该内存。例如,printf
可能已经为其内部使用分配了一个缓冲区,并且可能使用了相同的内存。
在大多数情况下,malloc
和 free
只是协调使用内存的方法,这样您的程序的不同部分就不会尝试同时使用同一内存不同的目的。当您的程序只有一部分使用分配的内存时,程序的其他部分不会干扰它。所以缺乏协调并没有导致你的程序失败。如果您的程序中有多个例程使用分配的内存,那么在释放内存后尝试使用内存更有可能遇到问题。
此外,一旦内存被释放,编译器可能会将指向它的指针视为没有固定值。 return t;
语句不需要 return 任何特定值。
您 free()
指向何处并不重要。一旦它是 free()
d,指针就不再是可延迟的(既不在函数内部也不在函数外部,它是 free()
d)
free()
的目的是 return 用 malloc()
分配的内存,所以语义是,一旦你释放了一块内存,它就不再可用了。
在C中,所有参数都是按值传递的,所以free()
不能改变你传递给它的值表达式,这就是指针不会变成无效指针值的原因(比如NULL
) 但建议您在不引发未定义行为的情况下不能再使用指针。
在free()
的设计中可以有一个解决方案,就是把保存指针的指针变量按地址传递,这样free()
就可以把指针变成一个NULL
。但这不仅需要做更多的工作,而且 free()
不知道你对 malloc()
给你的价值做了多少份......所以不可能知道你有多少引用有在那里作废。这种方法不可能赋予 free()
使对 returned 内存的引用无效的责任。
所以,如果你认为 free 不会将指针变成 NULL
并且出于某些奇怪的原因你仍然可以使用内存 returned,请不要再这样做了,因为你会犯错的。
建议您! :)