malloc';如果您没有';你不用它吗?

malloc';如果您没有';你不用它吗?,c,memory-leaks,free,malloc,C,Memory Leaks,Free,Malloc,考虑以下C代码: int main(){ int* c; c = (int*)malloc(sizeof(int)); c = 0xdeadbeef; free(c); return 0; } 这将是一个错误,因为您正试图释放c,这是以前没有被malloc'ed的东西。我的问题是,我刚才去的街区会发生什么?显然,c不再指向它,因此它不能被使用,但它仍然被视为“空闲”列表的一部分,还是这是一个显式内存泄漏?这是一个泄漏。当您的程序终

考虑以下C代码:

int main(){  
    int* c;  
    c = (int*)malloc(sizeof(int));  
    c = 0xdeadbeef;  
    free(c);  
    return 0;  
}

这将是一个错误,因为您正试图释放c,这是以前没有被malloc'ed的东西。我的问题是,我刚才去的街区会发生什么?显然,c不再指向它,因此它不能被使用,但它仍然被视为“空闲”列表的一部分,还是这是一个显式内存泄漏?

这是一个泄漏。当您的程序终止时,它将被操作系统回收。

假设您更改
c=7,则代码不会出错
*c=7

内存仍被分配,导致内存泄漏。你想要别的方式吗?机器/编译器确实没有办法知道您分配的内存应该被回收。如果这不是正确的行为,您的代码可能会正常运行:您永远不会真正信任代码


您可以在将来的某个时候重新指向该内存块,因此自动释放它会将地毯从您下方拉出。

请注意,
malloc()
返回的值不需要强制转换,因为转换
void*
->
int*
是自动的

您也可以这样重写调用:

c = malloc(sizeof *c);
int main(){  
    int* c;  
    c = (int*)malloc(sizeof(int));  
    c++;
    free(c);  
    return 0;  
}
因此,如果现在更改
c
的类型,则根本不必重写分配

[编辑]

最好检查分配是否成功(即
c!=NULL
)。

在malloc()之后,
c
是一个保存内存地址的变量。在这种情况下,
c
具有分配的第一个字节的内存地址值

当你说
c=7
时,你是说“
c
现在指向内存地址“7”。因为在本例中,内存地址“7”没有分配给进程,所以不能释放它。从理论上讲,内存地址“7”(或0xa73c930bf,或您将其设置为的任何值)确实分配给了进程,在这种情况下free()将成功

但是,在更改c的值之后,内存仍然被分配。您的进程仍然有内存和数据—您刚刚丢失了指针。你不知道记忆从哪里开始

这是一个不错的情况。在C语言中,可能有不同的变量指向该内存地址。您甚至可能有一个“int”,而不是存储该内存地址的“int*”。C不会试图跟踪您是否存储了那个特定的内存地址——实际上,它只是一个数字。这样做将是一项不可能的任务,因为任何跟踪的尝试都需要失去C指针提供的一些灵活性

所以要回答你的问题:因为你无法跟踪c的值,所以这个程序有内存泄漏。我的意思是,你拥有的内存不可能被你的程序使用,因此是在浪费资源


但是,当程序退出时,分配给您的进程的所有内存都将被释放,并可供其他程序使用。

请不要解雇我,但我不清楚您的问题是什么。很明显,你所做的与语言的意图直接冲突。这相当于说“如果我在汽车的油箱里装满了灭火器液体,仅仅因为灭火器的喷嘴正好插入油箱孔,会发生什么情况”。
我不是想成为一个混蛋,我只是不清楚为什么要问这个问题?我可以想到一大堆问题,它们利用了指针的强大功能,并想知道有多少种方法会错误地使用它们,从而导致应用程序失败。
如果你能找到正确的方法,你的代码*会做些什么呢?或者,您是否想知道是否有某种内部机制可以跟踪指针,并在意外丢失指针时帮助您回收内存?(如果是这样的话,这个问题已经在上面得到了回答。)

嗯,依我看,你在这一点上遇到的SEGFULT并不是因为你试图释放以前没有分配的内存,SEGFULT是因为你试图引用一个操作系统没有授予你权限的内存地址(这是分段故障的定义)

在一些实验中,假设您在valgrind中运行示例代码,您将得到以下输出:

==6945== Invalid free() / delete / delete[] ==6945== at 0x402265C: free (vg_replace_malloc.c:323) ==6945== by 0x80483D5: main (bla.c:6) ==6945== Address 0x7 is not stack'd, malloc'd or (recently) free'd ==6945== ==6945== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 1) ==6945== malloc/free: in use at exit: 4 bytes in 1 blocks. ==6945== malloc/free: 1 allocs, 1 frees, 4 bytes allocated. 运行此应用程序时,您将不再收到分段错误(由内核发出),而是收到glibc(malloc()和free()的所有者)的警告

edb@Flying-意大利面怪兽:/tmp$./a.out ***glibc检测到***./a.out:free():无效指针:0x0804a00c*** …后面跟着痕迹 因此,您试图释放一些内存,内核知道这些内存属于您,但glibc不记得将这些内存分发给您。如果您在valgrind中运行此操作(通过替换libc中的free()、malloc()、realloc()、…函数并自行执行记帐),您将得到以下输出:

==6955== Invalid free() / delete / delete[] ==6955== at 0x402265C: free (vg_replace_malloc.c:323) ==6955== by 0x80483D2: main (bla.c:5) ==6955== Address 0x418a02c is 0 bytes after a block of size 4 alloc'd ==6955== at 0x4022AB8: malloc (vg_replace_malloc.c:207) ==6955== by 0x80483C0: main (bla.c:3) ==6955== ==6955== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 1) ==6955== malloc/free: in use at exit: 4 bytes in 1 blocks. ==6955== malloc/free: 1 allocs, 1 frees, 4 bytes allocated. ==6955==无效的free()/delete/delete[] ==6955==0x402265C处:空闲(vg\u替换\u malloc.c:323) ==6955==0x80483D2:main(bla.c:5) ==6955==地址0x418a02c是大小为4的块分配后的0字节 ==6955==0x4022AB8:malloc(vg\u replace\u malloc.c:207) ==6955==0x80483C0:main(bla.c:3) ==6955== ==6955==错误摘要:1个上下文中的1个错误(已抑制:1中的11个) ==6955==malloc/free:在出口处使用:1个块中有4个字节。 ==6955==malloc/free:1个allocs,1个free,分配了4个字节。
free(c)可能会出错,因为free()将取消对垃圾指针的引用。Majd,您在技术上是正确的(最好的一种正确),但是将指针更改为一个极其无效的地址并尝试取消引用是他的全部目的。如果您更改 ==6955== Invalid free() / delete / delete[] ==6955== at 0x402265C: free (vg_replace_malloc.c:323) ==6955== by 0x80483D2: main (bla.c:5) ==6955== Address 0x418a02c is 0 bytes after a block of size 4 alloc'd ==6955== at 0x4022AB8: malloc (vg_replace_malloc.c:207) ==6955== by 0x80483C0: main (bla.c:3) ==6955== ==6955== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 1) ==6955== malloc/free: in use at exit: 4 bytes in 1 blocks. ==6955== malloc/free: 1 allocs, 1 frees, 4 bytes allocated.