如何正确释放函数返回的结构?
How to correctly free a structure returned from a function?
我是 C 的新手,正在尝试弄清楚如何处理从函数返回的结构和引用。
比如我想做的大概就是这样。
typedef struct test_t{
char *test_c;
} test_t;
int testFunc(test_t** output){
test_t* testStruct = malloc(sizeof(testStruct));
char* buf = malloc(sizeof(char) * 5);
strcpy(buf, "test");
testStruct->test_c = buf;
*output = testStruct;
return 0;
}
int main() {
test_t* test;
testFunc(&test);
printf("%s\n",test->test_c);
free(test);
return 0;
}
所以在 main 中我得到了测试结构。在 printf
之后(假设在 wards 之后有一些代码)我不再需要它并且想要释放它。但是如何正确地做呢?我应该先明确地解除分配 test_c 吗?但是如果没有分配呢?
结构可以像任何其他指针一样被释放。但是,您必须确保在执行此操作之前释放其所有分配的成员(否则很可能会导致结构成员的内存泄漏)。
typedef struct test_t{
char *test_c;
} test_t;
int testFunc(test_t** output){
test_t* testStruct = malloc(sizeof(testStruct));
char* buf = malloc(sizeof(char) * 5);
strcpy(buf, "test");
testStruct->test_c = buf;
*output = testStruct;
return 0;
}
int main() {
test_t* test;
testFunc(&test);
printf("%s\n",test->test_c);
free(test->test_c);
free(test);
return 0;
}
如果您的结构没有分配它的所有元素,您可以将它们的指针设置为 NULL
,一旦传递给 free (3)
就相当于什么都不做。
But how to do it properly? Should I just deallocate test_c explicitly first? But what if it wasn't allocated?
基本经验法则:如果您编写一个函数来分配资源,请编写一个补充函数来释放它。因此,当应用于您的示例时:
void testFree(test_t* toFree) {
free(toFree->test_c);
free(toFree);
}
...然后...
printf("%s\n",test->test_c);
testFree(test);
如果 testFree
与 testFunc
一起实现和公开,调用者不需要知道您的实现细节。这些函数本身作为同一个库的一部分,将确保不变量得到正确维护。如果您切换分配方案,则无需更改调用代码。您只需修改 testFree
以配合新的 testFunc
并重新 link.
首先,您需要释放为结构中的 char 分配的内存,前提是您已经初始化了它。否则,你会得到一个错误,所以在任何释放指令之前,你应该检查保存你试图释放的 test_p 的内存位置的指针是否不是 NULL。此外,free 指令应该以*test 作为参数,而不是test。
Should I just deallocate test_c explicitly first?
是的,您必须先释放 test_c
,因为如果释放 test
,您将失去对 test_c
的引用。
But what if it wasn't allocated?
当您从 testFunc
返回 int
时,您可以将其用作结构分配的状态(尽管恕我直言,返回指针会更好):
int testFunc(test_t** output){
test_t* testStruct = malloc(sizeof(testStruct));
if (testStruct == NULL)
/* testStruct allocation failure. */
return -1;
char* buf = malloc(sizeof(char) * 5);
if (buf == NULL) {
/* buf allocation failure. */
free(testStruct);
return -1;
}
strcpy(buf, "test");
testStruct->test_c = buf;
*output = testStruct;
return 0;
}
之后,您检查 testFunc
失败:
/* Check for allocation failure. */
if (testFunc(&test) == -1) {
fprintf(stderr, "Allocation error");
exit(EXIT_FAILURE);
}
/* Allocation succeeded. */
printf("%s\n",test->test_c);
free(test->test_c);
free(test)
您应该有一个分配和初始化 test_t
实例的过程。在 C++ 或其他面向对象的语言中,这将是一个构造函数。在 C 中,您必须自己滚动 - 类似于以下内容:
test_t *create_test_t(char *init_test_c)
{
test_t *tt;
tt = malloc(sizeof(test_t));
if(init_test_c != NULL)
{
tt->test_c = malloc(strlen(init_test_c)+1);
strcpy(tt->test_c, init_test_c);
}
else
tt->test_c = NULL;
}
您还需要一个函数来正确删除 test_t
实例。类似于:
void destroy_test_t(test_t *tt, bool static)
{
free(tt->test_c);
if(!static)
free(tt);
}
包含 static
参数以控制 tt
是否应该被释放。显然,您不想尝试释放指向 test_t
的静态实例的指针,在这种情况下,您会为 static
传递 TRUE。对于 test_t
的动态分配实例,例如那些使用 create_test_t
程序创建的,您将为 static
.
传递 FALSE
每次需要创建或销毁 test_t
时,您都可以使用这些函数。
祝你好运。
我是 C 的新手,正在尝试弄清楚如何处理从函数返回的结构和引用。
比如我想做的大概就是这样。
typedef struct test_t{
char *test_c;
} test_t;
int testFunc(test_t** output){
test_t* testStruct = malloc(sizeof(testStruct));
char* buf = malloc(sizeof(char) * 5);
strcpy(buf, "test");
testStruct->test_c = buf;
*output = testStruct;
return 0;
}
int main() {
test_t* test;
testFunc(&test);
printf("%s\n",test->test_c);
free(test);
return 0;
}
所以在 main 中我得到了测试结构。在 printf
之后(假设在 wards 之后有一些代码)我不再需要它并且想要释放它。但是如何正确地做呢?我应该先明确地解除分配 test_c 吗?但是如果没有分配呢?
结构可以像任何其他指针一样被释放。但是,您必须确保在执行此操作之前释放其所有分配的成员(否则很可能会导致结构成员的内存泄漏)。
typedef struct test_t{
char *test_c;
} test_t;
int testFunc(test_t** output){
test_t* testStruct = malloc(sizeof(testStruct));
char* buf = malloc(sizeof(char) * 5);
strcpy(buf, "test");
testStruct->test_c = buf;
*output = testStruct;
return 0;
}
int main() {
test_t* test;
testFunc(&test);
printf("%s\n",test->test_c);
free(test->test_c);
free(test);
return 0;
}
如果您的结构没有分配它的所有元素,您可以将它们的指针设置为 NULL
,一旦传递给 free (3)
就相当于什么都不做。
But how to do it properly? Should I just deallocate test_c explicitly first? But what if it wasn't allocated?
基本经验法则:如果您编写一个函数来分配资源,请编写一个补充函数来释放它。因此,当应用于您的示例时:
void testFree(test_t* toFree) {
free(toFree->test_c);
free(toFree);
}
...然后...
printf("%s\n",test->test_c);
testFree(test);
如果 testFree
与 testFunc
一起实现和公开,调用者不需要知道您的实现细节。这些函数本身作为同一个库的一部分,将确保不变量得到正确维护。如果您切换分配方案,则无需更改调用代码。您只需修改 testFree
以配合新的 testFunc
并重新 link.
首先,您需要释放为结构中的 char 分配的内存,前提是您已经初始化了它。否则,你会得到一个错误,所以在任何释放指令之前,你应该检查保存你试图释放的 test_p 的内存位置的指针是否不是 NULL。此外,free 指令应该以*test 作为参数,而不是test。
Should I just deallocate test_c explicitly first?
是的,您必须先释放 test_c
,因为如果释放 test
,您将失去对 test_c
的引用。
But what if it wasn't allocated?
当您从 testFunc
返回 int
时,您可以将其用作结构分配的状态(尽管恕我直言,返回指针会更好):
int testFunc(test_t** output){
test_t* testStruct = malloc(sizeof(testStruct));
if (testStruct == NULL)
/* testStruct allocation failure. */
return -1;
char* buf = malloc(sizeof(char) * 5);
if (buf == NULL) {
/* buf allocation failure. */
free(testStruct);
return -1;
}
strcpy(buf, "test");
testStruct->test_c = buf;
*output = testStruct;
return 0;
}
之后,您检查 testFunc
失败:
/* Check for allocation failure. */
if (testFunc(&test) == -1) {
fprintf(stderr, "Allocation error");
exit(EXIT_FAILURE);
}
/* Allocation succeeded. */
printf("%s\n",test->test_c);
free(test->test_c);
free(test)
您应该有一个分配和初始化 test_t
实例的过程。在 C++ 或其他面向对象的语言中,这将是一个构造函数。在 C 中,您必须自己滚动 - 类似于以下内容:
test_t *create_test_t(char *init_test_c)
{
test_t *tt;
tt = malloc(sizeof(test_t));
if(init_test_c != NULL)
{
tt->test_c = malloc(strlen(init_test_c)+1);
strcpy(tt->test_c, init_test_c);
}
else
tt->test_c = NULL;
}
您还需要一个函数来正确删除 test_t
实例。类似于:
void destroy_test_t(test_t *tt, bool static)
{
free(tt->test_c);
if(!static)
free(tt);
}
包含 static
参数以控制 tt
是否应该被释放。显然,您不想尝试释放指向 test_t
的静态实例的指针,在这种情况下,您会为 static
传递 TRUE。对于 test_t
的动态分配实例,例如那些使用 create_test_t
程序创建的,您将为 static
.
每次需要创建或销毁 test_t
时,您都可以使用这些函数。
祝你好运。