我是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
之后(假设病房后面有一些代码)我不再需要它并且想要解除分配它。但如何正确地做到这一点?我应该首先明确地释放test_c吗?但如果没有分配怎么办?
答案 0 :(得分:3)
可以像任何其他指针一样释放结构。但是,您必须确保在执行此操作之前释放其所有已分配的成员(如果不这样做,很可能会导致结构成员的内存泄漏)。
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)
就等同于什么都不做。
答案 1 :(得分:0)
但如何正确地做到这一点?我应该首先明确地释放test_c吗?但如果没有分配呢?
基本经验法则:如果您编写一个分配资源的函数,请编写一个解除分配资源的补充函数。因此,当应用于您的示例时:
void testFree(test_t* toFree) {
free(toFree->test_c);
free(toFree);
}
......然后......
printf("%s\n",test->test_c);
testFree(test);
如果testFree
与testFunc
一起实施并公开,则来电者无需了解您的实施细节。函数本身作为同一个库的一部分,将确保正确维护不变量。如果您切换分配方案,则不需要更改调用代码。您只需修改testFree
即可使用新的testFunc
并重新链接。
答案 2 :(得分:0)
首先,你需要释放你已经为结构中的char分配的内存,因为你已经初始化了它。否则,您将收到错误,因此在任何自由指令之前,您应该检查保存test_p的内存位置的指针是否正在尝试释放是否为空。此外,自由指令应该将* test作为参数而不是测试。
答案 3 :(得分:0)
我应该首先明确地释放test_c吗?
是的,您必须先释放test_c
,因为如果您免费test
,您将失去对test_c
的引用。
但如果没有分配呢?
当您从int
返回testFunc
时,您可以将其用作结构分配的状态(尽管如此,返回指针会更好主意恕我直言):
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)
答案 4 :(得分:0)
您应该有一个分配和初始化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
是否应该免费。{d}。显然,您不想尝试释放指向test_t
的静态实例的指针,在这种情况下,您为static
传递TRUE。对于test_t
的动态分配实例,例如那些使用create_test_t
程序创建的程序,您为static
传递FALSE。
每次需要创建或销毁test_t
时,都可以使用这些功能。
祝你好运。