Osk*_*son 3 c memory-management heap-memory
为什么我使用以下程序没有任何错误?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]){
char *pStr = (char*) malloc(25);
free(pStr);
strcpy(pStr, "foo");
printf("%s\n", pStr);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
不应该free(pStr)
阻止我写到那个地址?在使用它之前,我不必再分配空间吗?
free
只要事物在语法上是正确的,就不会阻止你做任何事情.因此,char*
如果您从未分配过内存,那么您仍然非常欢迎复制到正常情况.但这是未定义的行为,并且有责任(阅读:可能)导致程序崩溃或在没有警告的情况下做错事.
例如,如果您的编译器进行了一些优化,它可能会重新排序某些指令以节省时间.由于您释放了内存,编译器可能会认为在该位置为以后创建的其他数据分配内存是安全的.如果优化器移动该分配并在strcpy
此处之前写入,则可以覆盖存储在那里的对象.
考虑以下代码:
int main(int arc, char *argv[]){
char* pStr = (char*) malloc(25);
free(pStr);
strcpy(pStr, "foo");
printf("%s\n", pStr);
int* a = (int*) malloc(sizeof(int));
*a = 36;
printf("%d\n", *a);
}
Run Code Online (Sandbox Code Playgroud)
既然你写信给未分配的内存,你可以不知道什么任何的的printf
旨意显示.36可能已经覆盖了一些"foo"字符串."foo"字符串可能覆盖了a
指向的值36 .或者也许它们都没有影响到另一个,你的程序运行似乎很好,直到你改变一些变量的名称并重新编译,并且由于某种原因,即使你没有改变任何东西,一切都搞砸了.
故事的道德:你是正确的,你不应该写入free
记忆; 但是,你不能写入free
内存是不正确的.C不会检查这种情况,并假设您正在尝试做一些奇特的事情.如果您确切地知道编译器如何优化以及在malloc
调用时分配内存的位置,您可能知道在特定情况下写入未分配的内存是安全的,并且C不会阻止您这样做.但是对于99.999%的时间你不了解一切,就是不要这样做.