2

朋友们

在我们的 C++ 中,我目前使用 realloc 方法来调整 malloc 分配的内存大小。realloc() 用法如下完成

my_Struct *strPtr =(my_struct*)malloc(sizeof(my_Struct));

/* an later */

strPtr = (my_struct*)realloc(strPtr,sizeof(my_Struct)*NBR);

现在维基百科(_http://en.wikipedia.org/wiki/Malloc)说

如果相反,一个

void *p = malloc(orig_size);

/* and later... */

p = realloc(p, big_size);

那么如果无法获得 big_size 字节的内存,p 的值为 NULL,并且我们不再有指向先前为 p 分配的内存的指针,从而造成内存泄漏

它还说纠正上述错误的正确方法是

void *p = malloc(orig_size);

/* and later... */

void *tmp = realloc(p, big_size); 

if (tmp != NULL)
 {

p = tmp; /* OK, assign new, larger storage to p */

} 

else 

{

/* handle the problem somehow */

}

你能告诉我哪个是使用 realloc() 的最佳方式吗

同样,一旦我有了指向结构的指针,然后在稍后使用 realloc 时,我可以使用指向 void 的指针吗?

非常感谢

4

6 回答 6

7

当然你必须防止realloc()返回的情况NULL。这是一种内存分配,在 C 中(其中realloc())主要使用,我认为 C++ 程序员认为使用原始调用有点低级/qaint realloc(),内存分配总是会失败。

直接用返回值覆盖指针是错误的,因为这会丢弃原始指针并在重新分配失败的情况下导致内存泄漏。

于 2009-03-09T13:04:54.943 回答
5

Malloc() 和 realloc() 是 C 函数。实际上, realloc() 执行 malloc() 和 free() 取决于您传递的参数:

  • 如果你传递一个空指针,realloc 会做 malloc 做的事情。
  • 如果您将其传递为零大小,则 realloc 会执行 free 的操作。

引自这里,你有更深入的解释。

C 库无法就地扩展内存块,因此 C++ 也不支持它。

如果您想坚持使用 C 函数,那么您应该在调用 realloc() 时保留第一次内存分配的指针。然后检查它是否为 NULL,否则分配它,就像在上一个代码中所做的那样。

但也许对于 C++,最好的解决方案是制作自己的 mallocator,即基于 C 的 malloc() 的 std 解决方案。检查这个,或者这个

于 2009-03-09T13:32:21.537 回答
1

使用建议的方法——保持指向前一个缓冲区的指针,直到 realloc 成功返回。一旦 realloc() 成功返回前一个块已经被释放并且所有指向它的指针都变得悬空 - 调整它们。

realloc 和 malloc 不关心指针类型是什么——你可以使用 void* 以及任何东西*。

于 2009-03-09T13:06:10.307 回答
0

正如其他人所说,只需按照建议正确使用 realloc 即可。

但是这样做的“C++ 方式”实际上是使用 std::vector<> 而不是自己维护数组。这样,C++ 标准库将处理重新分配的低级细节(可能通过使用 realloc())。

于 2009-03-09T14:32:06.667 回答
0

当 realloc() 失败并返回 NULL 时,原始内存保持不变。
所以你应该像这样使用它:

my_Struct* strPtr =(my_struct*)malloc(sizeof(my_Struct));

/* an later */

my_Struct* tmp = (my_struct*)realloc(strPtr,sizeof(my_Struct)*NBR);
if (tmp != NULL)
{
    strPtr = tmp;
}
else
{
    /* realloc Failed. Need to do something */
}
于 2009-03-09T14:44:15.967 回答
0

为什么要使用 malloc 和 realloc?C++ 中几乎总是有更好的方法。

如果您使用它来制作可变长度数组,则几乎可以肯定使用 std::vector<> 或其他容器模板之一会更好。

如果您使用 C 代替,可能使用支持 C++ 的编译器,那么正确的方法是第二种方法,它在分配失败时不会丢失整个内存块。

第二个问题的答案还取决于您使用的是 C 还是 C++。在 C 中,void * 是一种通用数据指针类型,可以自由转换。在 C++ 中,void * 需要显式转换。如果您实际上正在编写 C,则需要使用 malloc() 和朋友,它们适用于 void *。如果你真的在写 C++,你需要强制转换,这让它更尴尬。在这两种情况下,realloc() 都不适用于指向 struct 的指针,而是适用于指向 void 的指针。

于 2009-03-09T14:55:56.360 回答