这已成为困扰我多年的事情.
我们都在学校(至少,我是)教过你必须释放每个分配的指针.不过,我有点好奇,关于不释放内存的实际成本.在一些明显的情况下,就像在malloc
循环内部或线程执行的一部分中调用时一样,释放是非常重要的,因此没有内存泄漏.但请考虑以下两个例子:
首先,如果我的代码是这样的:
int main()
{
char *a = malloc(1024);
/* Do some arbitrary stuff with 'a' (no alloc functions) */
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这里真正的结果是什么?我的想法是,进程死了,然后堆空间无论如何都没有了,因此错过调用没有任何害处free
(但是,我确实认识到无论如何都要将它关闭,可维护性和良好实践的重要性).我对这个想法是对的吗?
其次,假设我的程序有点像shell.用户可以声明类似的变量,aaa = 123
并将其存储在某些动态数据结构中供以后使用.很明显,你可以使用一些解决方案来调用一些*alloc函数(hashmap,链表,类似的东西).对于这种程序,在调用之后永远自由是没有意义的,malloc
因为这些变量必须在程序执行期间始终存在,并且没有好的方法(我可以看到)用静态分配的空间来实现它.拥有一堆已分配但仅作为流程结束的一部分释放的内存,这是不好的设计吗?如果是这样,有什么替代方案?
在C编程中,您可以将任何类型的指针作为参数传递给free,它如何知道要释放的已分配内存的大小?每当我传递指向某个函数的指针时,我也必须传递大小(即10个元素的数组需要接收10作为参数来知道数组的大小),但我不必将大小传递给自由功能.为什么不,并且我可以在我自己的函数中使用相同的技术来避免需要购买数组长度的额外变量?
我想知道如何malloc
和free
工作.
int main() {
unsigned char *p = (unsigned char*)malloc(4*sizeof(unsigned char));
memset(p,0,4);
strcpy((char*)p,"abcdabcd"); // **deliberately storing 8bytes**
cout << p;
free(p); // Obvious Crash, but I need how it works and why crash.
cout << p;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果答案在记忆水平上是深入的,如果可能的话,我将非常感激.
在我的公司中,有一个编码规则,在释放任何内存后,将变量重置为NULL.例如 ...
void some_func ()
{
int *nPtr;
nPtr = malloc (100);
free (nPtr);
nPtr = NULL;
return;
}
Run Code Online (Sandbox Code Playgroud)
我觉得,在上面显示的代码中,设置为NULL没有任何意义.或者我错过了什么?
如果在这种情况下没有任何意义,我将采用"质量团队"来删除此编码规则.请指教.
从理论上讲,我可以这么说
free(ptr);
free(ptr);
Run Code Online (Sandbox Code Playgroud)
是一个内存损坏,因为我们释放已经释放的内存.
但是如果
free(ptr);
ptr=NULL;
free(ptr);
Run Code Online (Sandbox Code Playgroud)
由于操作系统将以不确定的方式运行,我无法对此进行实际的理论分析.无论我在做什么,这种记忆是否会腐败?
释放空指针有效吗?
我正在阅读一本使用 C的书(Butenhof 的POSIX 线程编程,1997 年),我遇到了以下行:
(void)free(data);
Run Code Online (Sandbox Code Playgroud)
这里,data
只是一个指向已分配结构的指针,
data = malloc(sizeof(my_struct_t));
Run Code Online (Sandbox Code Playgroud)
为什么是free
被强制转换的结果void
?
根据我对 C 的理解,这似乎没有意义,原因有两个:
void
这本书写于 1997 年。这是某种遗产吗?
作者提到这些示例是在 Digital Unix 4.0d 上运行的,但如果您不打算使用该结果,我仍然无法想象有理由强制转换该函数的结果。
需要明确的是:我确实知道这一点malloc
并free
在C库中实现,C库通常从操作系统中分配大块内存并进行自己的管理,将较小的内存分配到应用程序并跟踪分配的字节数.这个问题不是免费如何知道免费的多少.
相反,我想知道为什么free
首先这样做.作为一种低级语言,我认为要求C程序员不仅要跟踪分配的内存而且要跟踪多少内容(事实上,我通常发现我最终会跟踪字节数)是完全合理的无论如何都是malloced).在我看来,明确给出字节数free
可能允许一些性能优化,例如,具有不同分配大小的单独池的分配器将能够通过查看输入参数来确定要从哪个池中释放,以及总体而言,空间开销会减少.
因此,简而言之,为什么这些malloc
和free
创造,使得他们必须在内部跟踪的字节数的分配呢?这只是一次历史性事故吗?
一个小编辑:有些人提供了诸如"如果你释放的金额与你分配的金额不同"的分数.我想象的API可能只需要一个就可以完全释放分配的字节数; 释放更多或更少可能只是UB或实现定义.不过,我不想劝阻讨论其他可能性.
当我运行我的(C++)程序时,它会因此错误而崩溃.
*glibc检测到* ./load:双重免费或损坏(!prev):0x0000000000c6ed50***
如何追踪错误?
我尝试使用print(std::cout
)语句,没有成功.可以gdb
让这更容易吗?
我怎么能免费const char*
?我分配了新内存使用malloc
,当我试图释放它时,我总是收到错误"不兼容的指针类型"
导致这种情况的代码如下:
char* name="Arnold";
const char* str=(const char*)malloc(strlen(name)+1);
free(str); // error here
Run Code Online (Sandbox Code Playgroud) 我正在尝试学习C而我正在尝试编写一个基本的堆栈数据结构,但我似乎无法获得基本malloc
/ free
正确.
这是我一直在使用的代码(我只是在这里发布一小部分来说明一个特定的问题,而不是总代码,但错误消息是通过运行此示例代码生成的valgrind
)
#include <stdio.h>
#include <stdlib.h>
typedef struct Entry {
struct Entry *previous;
int value;
} Entry;
void destroyEntry(Entry entry);
int main(int argc, char *argv[])
{
Entry* apple;
apple = malloc(sizeof(Entry));
destroyEntry(*(apple));
return 0;
}
void destroyEntry(Entry entry)
{
Entry *entry_ptr = &entry;
free(entry_ptr);
return;
}
Run Code Online (Sandbox Code Playgroud)
当我运行它valgrind
时--leak-check=full --track-origins=yes
,我收到以下错误:
==20674== Invalid free() / delete / delete[] / realloc()
==20674== at 0x4028E58: free (vg_replace_malloc.c:427)
==20674== by 0x80485B2: destroyEntry (testing.c:53)
==20674== by 0x8048477: …
Run Code Online (Sandbox Code Playgroud) c ×10
free ×10
malloc ×5
pointers ×3
c++ ×2
casting ×1
coding-style ×1
const ×1
debugging ×1
heap-memory ×1
legacy-code ×1
null ×1
size ×1
void ×1