将堆内存设置为空闲状态并不像在C中那样有效
我有这个代码片段来理解C中的内存管理函数将堆内存设置为空闲状态并不像在C中那样有效,c,memory-management,free,C,Memory Management,Free,我有这个代码片段来理解C中的内存管理函数void free(void*)。我所知道的free函数是它将释放由指针管理的内存。我想看看一块内存被释放后会发生什么,以及该内存块是否仍然可以访问关联的指针 #include <stdio.h> #include <stdlib.h> #include <string.h> #define STR_SIZE 20 int main(int argc, char *argv[]) { char origina
void free(void*)
。我所知道的free
函数是它将释放由指针管理的内存。我想看看一块内存被释放后会发生什么,以及该内存块是否仍然可以访问关联的指针
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STR_SIZE 20
int main(int argc, char *argv[])
{
char originalChar [] = "123456789";
char *myChar = (char*) malloc(sizeof(char) * STR_SIZE);
if (!myChar) {
printf("allocation failed!");
exit(1);
}
char *isOk = strncpy(myChar, originalChar, STR_SIZE*sizeof(char));
if(!isOk) exit(1);
char *myCharCopy = myChar;
printf("oC = %d, mCC = %d; mC = %d\n", originalChar, myCharCopy, myChar);
printf("The strings = %s\n", myChar);
printf("The strings = %s\n", myCharCopy);
free(myChar);
printf("----- free happened here -----\n");
// myChar = NULL;
printf("oC = %d, mCC = %d; mC = %d\n", originalChar, myCharCopy, myChar);
printf("The strings = %s\n", myChar);
printf("The strings = %s\n", myCharCopy);
return 0;
}
这个结果对我来说意义不大。因为
free
函数应该设置释放内存块,但它不是结果。这里究竟发生了什么事?此外,与堆上内存相关联的指针似乎仍然可以被释放的内存访问。为什么会发生这种情况?根据C11
标准第§7.22.3.3章的free
功能
free
函数使ptr
指向的空间被释放,即生成
可供进一步分配。[..]
它并不要求将指针设置为NULL(或任何其他值)free()
-ing只是向操作系统表明,可以在需要时回收和重新发布分配的内存
访问空闲()。因此,一旦调用了free()
,您就不应该再访问指针了
正是由于这个原因,通常认为在调用free()
之后立即将free()
-d指针设置为NULL是一种好的做法,以避免对已释放内存的任何意外访问
也就是说
printf("oC = %d, mCC = %d; mC = %d\n", originalChar, myCharCopy, myChar);
还调用%d
是打印int
,而不是指针(或字符串)。如果要打印地址,您可能需要使用
printf("oC = %p, mCC = %p; mC = %p\n", (void*)originalChar, (void*)myCharCopy, (void*)myChar);
根据C11
标准第§7.22.3.3章的规定,免费
功能
free
函数使ptr
指向的空间被释放,即生成
可供进一步分配。[..]
它并不要求将指针设置为NULL(或任何其他值)free()
-ing只是向操作系统表明,可以在需要时回收和重新发布分配的内存
访问空闲()。因此,一旦调用了free()
,您就不应该再访问指针了
正是由于这个原因,通常认为在调用free()
之后立即将free()
-d指针设置为NULL是一种好的做法,以避免对已释放内存的任何意外访问
也就是说
printf("oC = %d, mCC = %d; mC = %d\n", originalChar, myCharCopy, myChar);
还调用%d
是打印int
,而不是指针(或字符串)。如果要打印地址,您可能需要使用
printf("oC = %p, mCC = %p; mC = %p\n", (void*)originalChar, (void*)myCharCopy, (void*)myChar);
根据:
7.22.3.3免费
功能
free
功能使ptr
指向的空间
已解除分配,即可供进一步分配。如果ptr
是空指针,不会发生任何操作。否则,如果参数
与内存管理函数先前返回的指针不匹配,
或者,如果通过调用free
或realloc
释放了空间,则行为未定义
但是现在您的代码再次按照C标准访问调用未定义行为的内存:
J.2未定义的行为
1在以下情况下,该行为未定义:
指针的值,该指针引用通过调用释放的空间
使用free
或realloc
功能(7.22.3)
包括看起来“工作”。根据:
7.22.3.3免费
功能
free
功能使ptr
指向的空间
已解除分配,即可供进一步分配。如果ptr
是空指针,不会发生任何操作。否则,如果参数
与内存管理函数先前返回的指针不匹配,
或者,如果通过调用free
或realloc
释放了空间,则行为未定义
但是现在您的代码再次按照C标准访问调用未定义行为的内存:
J.2未定义的行为
1在以下情况下,该行为未定义:
指针的值,该指针引用通过调用释放的空间
使用free
或realloc
功能(7.22.3)
包括显示为“工作”。C不支持OOP。因此,没有托管指针等,也没有调用未定义行为获得的信息。不要在C中使用malloc
&friends的结果。无意冒犯,但善意的建议:在尝试利用UB之前,您应该正确掌握基本知识。谢谢。我刚刚看到有人做了(char*)malloc(…)
,我不知道这是不是一个错误@奥拉夫。它是C++中需要的,但是在C中应该避免使用(参见@ SuravgHoHS的评论)。另外,sizeof(char)
被定义为产生1
使用它是毫无意义的。C不支持OOP。因此,没有托管指针等,也没有调用未定义行为获得的信息。不要在C中使用malloc
&friends的结果。无意冒犯,但善意的建议:在尝试利用UB之前,您应该正确掌握基本知识。谢谢。我刚刚看到有人做了(char*)malloc(…)
,我不知道这是不是一个错误@奥拉夫。它是C++中需要的,但在C中应该避免(SE)。