在C语言中,分配和释放内存最安全的方法是什么?

在C语言中,分配和释放内存最安全的方法是什么?,c,memory-management,C,Memory Management,使用C,有没有比使用malloc更安全的内存分配方法?例如,是否有一个相当于智能指针的C语言,或者有人提出的一些方便的函数,可以使分配过程更干净一些?我的意思是,当然,这只是一行,但必须有一个更简洁的方式来完成它。我想这个问题的解除分配部分包括在C中是否有类似于智能指针的东西。为什么不直接使用堆栈?如果你真的觉得C的标准内存管理太不安全,您应该通过切换到另一种为您进行内存管理的编程语言,或者使用一个也为您进行内存管理的垃圾收集器来避免这种情况,例如Boehm的: 智能指针帮助C++,但仍然需要

使用C,有没有比使用malloc更安全的内存分配方法?例如,是否有一个相当于智能指针的C语言,或者有人提出的一些方便的函数,可以使分配过程更干净一些?我的意思是,当然,这只是一行,但必须有一个更简洁的方式来完成它。我想这个问题的解除分配部分包括在C中是否有类似于智能指针的东西。

为什么不直接使用堆栈?

如果你真的觉得C的标准内存管理太不安全,您应该通过切换到另一种为您进行内存管理的编程语言,或者使用一个也为您进行内存管理的垃圾收集器来避免这种情况,例如Boehm的:


智能指针帮助C++,但仍然需要意识,即当你构建循环结构时,

你可以编写自己的垃圾回收器。如果你找不到或者没有那种时间,答案是否定的。这是人们使用C++的主要原因之一,与MalC/C++MyLoc相比,自动化资源管理是难以置信的。如果您能负担得起GC的性能,只需使用一种更快(开发速度更快)的语言即可。唯一的解决方案是进入C++,既不需要垃圾回收器也不需要手动内存管理。< /P> < P>使用Maloc和ReLoC,然后用Valgrind进行广泛的测试。使用类似Boehm遗嘱的GC。如果您使用的是C,那么就使用C。一个值得研究的库是halloc

分配内存最安全的方法就是简单地了解它是如何正常工作的。如果你想要一种安全的语言,使用一种安全的语言。例如,Java已经实现了自动垃圾收集

如果你想使用C,你最好的办法就是在它的辉煌中拥抱它。你可能会在某个时候被灼伤,但伴随着痛苦,你会有经验

我一直认为对学生有用的一件事是,把每一次分配都看作是一种额外的信息,即责任。你把内存块的责任和内存本身一起传递,谁是最后一个被赋予责任的人,谁就必须释放它


此外,没有两段代码可以同时具有响应性。换句话说,当您将内存传递给另一方时,在它被返回之前,您不允许触摸它。

分配过程似乎足够清楚:每个malloc-ed块都应该被释放。我想到的最简单的下一步(在GC之前)是编写一个“跟踪”您的分配的函数,因此,在代码/函数退出时,您可以在单个函数调用中释放不再需要的所有内容(当然,另一个函数允许像往常一样释放单个块)。这将增加一点内存使用量,但一旦正确实现,将更容易在一次放炮中逐个释放分配的块

用法类似于:

MemPool *pool = mempool_create();

// use
char *t = mempool_alloc(pool, size);
// ...
char *b = mempool_alloc(pool, size2);
// ...
int *c = mempool_alloc(pool, xy * sizeof(int));
// free a single piece for whatever reason...
mempool_free(pool, b);
// ...

// when you finished with this "pool":
mempool_destroy(pool);

这至少可以确保“池”中分配的所有内容都可以通过
mempool\u destroy
释放,因此在最坏的情况下,您可以使用“池”机制分配所有内容,并在不再需要时释放所有内容(例如,在函数退出时)。(可能“pool”不是一个合适的名称)

无论出于何种原因,人们通常不会使用堆栈。为什么不呢?因为内存在退出函数后将无法生存,所以-)+1 Valgrind才是正确的选择。在C中使用gc是完全错误的:-)。如果gc延迟不是问题,那么无论如何都不应该使用C+1代表瓦尔格林。哈洛克图书馆看起来很有趣。这更接近我最初提出这个问题时的想法。我喜欢Valgrind,但我怀疑这种联系与考虑使用垃圾收集器的C开发人员有多大关系。大多数人都没有编写高性能、基于协同程序的Web服务器。-1抱歉:您关于GC的警告只适用于少数应用程序。虽然我自己很少使用GC,但我使用它的频率比使用ucontext要高。像safe_free(void*ptr){free(ptr);ptr=NULL;}之类的函数怎么样?或者使用某种结构包装器和函数来操作它呢?它应该是
void**ptr
free(*ptr)*ptr=NULL
;关于我的
mempool.*
示例,请注意
mempool.\u free(pool,b)
如果地址b不在池中,则可以无提示地执行任何操作;然而,要添加额外的nullifb,您应该更改prototype,以便
(pool,&b)
是您所需要的;但它并不总是可以要求的,因此,imo应该给出一个只接受ptr的“正常”版本。这是一个很好的建议,但它并不能真正回答问题。你基本上是在说,不要努力编写代码,这样可以让你以更安全的方式编写未来的代码。取而代之的是,要么使用一种内置了这些功能的语言,要么让自己承担起安全处理内存的负担。在编写代码时,我更喜欢尽可能地减少自己的工作量,这样我可以更多地关注待解决的问题,而不是实现的细节。把细节抽象出来通常是件好事,你不认为吗?是的,我确实认为把细节抽象出来是件好事。我不同意你的意见的地方在于应该抽象出什么层次的细节。想尽一切办法把复杂的东西,如链表或其他集合和数据结构抽象掉。但是malloc家族是C的一个非常基本和易于使用的核心部分(这可能是因为我已经切割C代码超过三十年了)。抽象出像内存管理这样的复杂性是一个好主意。我同意paxdiablo的说法,malloc、realloc和free都很容易使用。我想我只是想让他们更容易。对我来说,尝试优化我需要做的输入量是很常见的(t