更安全的重新分配方式
Safer way to realloc
我正在实现一个安全地重新分配结构的功能,以便在发生任何分配错误时不丢失信息,如下所示:
int foo (someStruct_t *ptr, int size)
{
someStruct_t *tmp_ptr;
tmp_ptr = realloc(ptr, size);
if (tmp_ptr == NULL)
return -1;
ptr = tmp_ptr;
return 0;
}
我的疑问在于:每次我 运行 这个函数时,我是否都没有复制为结构分配的内存?按照我的想法,我应该在退出之前释放其中一个指针,对吗?
这里主要的主要问题是,在调用 foo()
之后,在调用方中,传递给 ptr
的参数将不会更改,因为它本身是按值传递的。
您需要将指针传递给您想要重新分配的指针,以防您不想return
新指针。
也就是说,这里没有 "duplication" 内存。
从realloc()
的角度
realloc()
,如果成功,returns 指向新内存的指针并处理旧内存的取消分配工作。您无需担心任何重复或内存泄漏。
引用 C11
,章节 §7.22.3.5(强调我的)
The realloc
function deallocates the old object pointed to by ptr
and returns a
pointer to a new object that has the size specified by size
. [....]
[....] If memory for the new object cannot be
allocated, the old object is not deallocated and its value is unchanged.
从赋值来看
像ptr = tmp_ptr;
这样的语句不会复制指针指向的内存或内存内容,它只是拥有同一个指针的两个副本。例如,您可以将它们中的任何一个传递给 free()
.
所以,归根结底,要回答问题中的 "question",
In my line of thought I should free one of the pointers before exiting, correct?
不,你不应该。您需要让新分配的指针在调用者中有用,free()
-在被调用函数中使整个函数毫无意义。不过,您应该从调用者那里释放指针。
int foo (someStruct_t **ptr, int size)
{
someStruct_t *tmp_ptr;
tmp_ptr = realloc(*ptr, size);
if (tmp_ptr == NULL)
return -1;
*ptr = tmp_ptr;
return 0;
}
发布的代码包含几个问题:
- 无法在没有指针地址的情况下更改调用者指针指向的位置,因此在参数列表中使用
**
并使用以下方式调用函数:foo( &ptr, size);
- 每个对调用者指针的引用现在都必须通过
*
取消引用
- 通常大小是指要分配的条目数房间,所以
size
需要乘以sizeof( someStruct_t )
- 请注意
size_t
用于 size
参数,因为 realloc()
期望第二个参数具有以下类型:size_t
现在建议的代码:
#include <stdlib.h> // realloc()
int foo (someStruct_t **ptr, size_t size)
{
someStruct_t *tmp_ptr;
tmp_ptr = realloc( *ptr, sizeof( someStruct_t) * size );
if (tmp_ptr == NULL)
return -1;
*ptr = tmp_ptr;
return 0;
} // end function: foo
我正在实现一个安全地重新分配结构的功能,以便在发生任何分配错误时不丢失信息,如下所示:
int foo (someStruct_t *ptr, int size)
{
someStruct_t *tmp_ptr;
tmp_ptr = realloc(ptr, size);
if (tmp_ptr == NULL)
return -1;
ptr = tmp_ptr;
return 0;
}
我的疑问在于:每次我 运行 这个函数时,我是否都没有复制为结构分配的内存?按照我的想法,我应该在退出之前释放其中一个指针,对吗?
这里主要的主要问题是,在调用 foo()
之后,在调用方中,传递给 ptr
的参数将不会更改,因为它本身是按值传递的。
您需要将指针传递给您想要重新分配的指针,以防您不想return
新指针。
也就是说,这里没有 "duplication" 内存。
从
realloc()
的角度realloc()
,如果成功,returns 指向新内存的指针并处理旧内存的取消分配工作。您无需担心任何重复或内存泄漏。引用
C11
,章节 §7.22.3.5(强调我的)The
realloc
function deallocates the old object pointed to byptr
and returns a pointer to a new object that has the size specified bysize
. [....][....] If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged.
从赋值来看
像
ptr = tmp_ptr;
这样的语句不会复制指针指向的内存或内存内容,它只是拥有同一个指针的两个副本。例如,您可以将它们中的任何一个传递给free()
.
所以,归根结底,要回答问题中的 "question",
In my line of thought I should free one of the pointers before exiting, correct?
不,你不应该。您需要让新分配的指针在调用者中有用,free()
-在被调用函数中使整个函数毫无意义。不过,您应该从调用者那里释放指针。
int foo (someStruct_t **ptr, int size)
{
someStruct_t *tmp_ptr;
tmp_ptr = realloc(*ptr, size);
if (tmp_ptr == NULL)
return -1;
*ptr = tmp_ptr;
return 0;
}
发布的代码包含几个问题:
- 无法在没有指针地址的情况下更改调用者指针指向的位置,因此在参数列表中使用
**
并使用以下方式调用函数:foo( &ptr, size);
- 每个对调用者指针的引用现在都必须通过
*
取消引用
- 通常大小是指要分配的条目数房间,所以
size
需要乘以sizeof( someStruct_t )
- 请注意
size_t
用于size
参数,因为realloc()
期望第二个参数具有以下类型:size_t
现在建议的代码:
#include <stdlib.h> // realloc()
int foo (someStruct_t **ptr, size_t size)
{
someStruct_t *tmp_ptr;
tmp_ptr = realloc( *ptr, sizeof( someStruct_t) * size );
if (tmp_ptr == NULL)
return -1;
*ptr = tmp_ptr;
return 0;
} // end function: foo