而不是只使用free()并指针指向一些新块,如何真正清空以前指向的内存块?
我试图使用free()释放动态分配的内存,但我发现它的作用是让参数指针指向某个新位置,并保留以前指向的位置,内存未被清除。 如果我再次使用malloc,指针可能指向这个凌乱的块,它已经充满垃圾,这真的很烦人..
我是C的新手,我认为c ++中的delete []没有这个问题。 有什么建议吗?
谢谢
为什么新分配的内存充满垃圾“真的很烦人”? 如果你分配内存,大概是因为你将把它用于某些东西 – 这意味着你必须在尝试阅读它之前存储一些有意义的值。 在大多数情况下,在编写良好的代码中,没有理由关心新分配的内存中的内容。
如果您碰巧需要新分配的内存块,可以在调用malloc
后调用memset
,或者可以使用calloc
而不是malloc
。 但要仔细考虑这样做是否有任何实际优势。 如果您实际上要使用那些全位零值(即,如果所有位零恰好是我上面提到的“有意义的值”),请继续并清除该块。 (但请记住,该语言不能保证空指针或浮点数0.0表示为全位 – 零,尽管它在大多数实现中都是。)
并且free()
不会“将参数指针指向某个新位置”。 free(ptr)
使free(ptr)
指向的内存可用于将来的分配。 它不会改变指针对象ptr
本身的内容(尽管存储在ptr
中的地址确实变得无效)。
通过free
,内存刚刚从使用中释放。 它被分配给你释放。 它没有明确清除。 某些旧内容可能存在于这些内存位置。 为避免这种情况,有两种解决方案。
解决方案1:
在使用malloc
分配内存后,您需要执行memset
。
代码示例:
unsigned int len = 20; // len is the length of boo char* bar = 0; bar= (char *)malloc(len); memset(bar, 0, len);
解决方案2:
或者使用calloc()
,默认情况下将内存初始化为0
。
代码示例:
int *pData = 0; int i = 10; pData = (int*) calloc (i,sizeof(int));
我认为c ++中的delete[]
没有这个问题。
没有
它的行为完全相同。 除非您将指针显式设置为0
,否则delete
‘d指针将不会指向0
。 所以在删除指针后总是将指针设置为0
。
什么时候应该使用malloc
不是calloc
,反之亦然?
由于calloc
将分配的内存设置为0
这可能需要一些时间,所以如果性能问题,你可能想要使用malloc()
。(Ofcourse One最常见的用途,看看这是否真的有问题)
如果初始化内存更重要,请使用calloc()
因为它明确地为您执行。
此外,某些操作系统(如Linux)具有Lazy Allocation内存模型,其中返回的内存地址是虚拟地址,实际分配仅在运行时发生。 操作系统假定它能够在运行时提供此分配。
在程序实际触摸它之前, malloc
分配的malloc
不受实际内存的支持。
同时,由于calloc
将内存初始化为0
,因此可以确保操作系统已经使用实际RAM(或交换)支持分配。
realloc
怎么样?
是的,与malloc
类似的行为。
摘录自文档 :
void * realloc ( void * ptr, size_t size );
重新分配内存块
ptr参数指向的内存块大小更改为大小字节,从而扩展或减少块中可用的内存量。
该function可以将存储块移动到新位置,在这种情况下返回新位置。 即使移动了块,内存块的内容也会保留到新旧大小中的较小者。如果新大小较大,则新分配的部分的值是不确定的。
如果ptr为NULL,则该函数的行为与malloc完全相同,分配一个大小字节的新块并返回指向它开头的指针。
如果大小为0,则先前在ptr中分配的内存被释放,就像调用free一样,并返回NULL指针。
您可以使用calloc( )
而不是malloc( )
将已分配的内存清除为零。