返回结构指针

假设我有以下结构和函数返回一个指针:

typedef struct { int num; void *nums; int size; } Mystruct; Mystruct *mystruct(int num, int size) { //Is the following correct? Is there a more efficient way? Mystruct mystruct; mystruct.num = num; mystruct.size = size; mystruct.nums = malloc(num*sizeof(size)); Mystruct *my; *my = mystruct; return my; } 

我想使用上面的函数定义任何Mystruct指针。 我应该声明一个Mystruct变量,定义Mystruct的属性,指定它的指针,并返回指针或通过指针立即定义mystruct属性的属性?

我应该声明一个Mystruct变量,定义Mystruct的属性,为它指定一个指针,然后返回指针

绝对不是,因为函数中定义的变量(在“auto”存储类中)将在函数退出时消失,并且您将返回一个悬空指针。

你可以接受一个指向Mystruct的指针(调用者负责分配它)并填写它; 或者,您可以使用malloc创建一个新的(调用者有责任在完成后释放它)。 第二个选项至少可以让你保持你似乎热衷的function签名:

 Mystruct *mystruct(int num, int size) { Mystruct *p = malloc(sizeof(MyStruct)); .... return p; } 

但它通常是次要的 – 因为调用者无论如何都必须承担责任,也可以使用第一个选项并可能获得性能(如果调用者可以使用自动类实例,因为它知道使用范围是有限的) 。

您不能使用该变量,因为它将在函数退出时被释放。 例如:

 Mystruct *mystruct(int num, int size) { MyStruct x; x.num = 1; ... return &x; } 

将出现分段错误或访问冲突,因为一旦退出,x的内存就会被释放。 所以你必须为结构分配内存(并确保稍后释放)或声明一个永远存在的全局。 后者的例子……

 Mystruct *mystruct(int num, int size) { MyStruct *x; x = (MyStruct*)malloc( sizeof( MyStruct ) ); x->num = 1; ... return x; } 

如果您正在编写通用代码而您不知道如何使用它,那么提供这两个选项是很好的:

 int mystructm(Mystruct *storage, int num, int size) { int rv = 0; storage->num = num; storage->size = size; storage->nums = malloc(num*sizeof(size)); if (!storage->nums) return -1; return 0; } Mystruct *mystruct(int num, int size) { Mystruct *mp = (Mystruct *)malloc(sizeof(Mystruct)); if (mp) { if (mystructm(mp, num, size) == -1) { free(mp); mp = NULL; } } return mp; } 

这个想法是,作为一个库编写者,你不应该指定策略(例如每个Mystruct必须动态分配),但应该让应用程序编写者决定。

重要的是要记住,指针不是您分配给结构的东西,而是指针指示您希望将其视为结构的内存中的位置。 根据您的问题,您确实希望分配内存来保存数据结构。 这为您提供了指向已分配内存位置的指针。 一旦你有了,你可以退货。


编辑 (编辑原始问题后)查看您对问题的编辑,您肯定会遇到“我的”指针问题。 这是未初始化的,可能指向内存中的任何位置。 当您尝试将结构复制到它时,您可能会遇到seg-fault。

分配一个新的Mystruct并返回一个指向它的指针通常看起来或多或少是这样的:

 Mystruct *mystruct(int num, int size) { Mystruct *result; result = malloc(sizeof(MyStruct)); if (!result) return NULL; result->num = num; ... return result; } 

稍后,当您完成使用malloc分配的Mystruct ,应该使用free()再次释放它。

只声明一个局部变量并返回指向该局部变量的指针将不起作用。 局部变量超出了函数末尾的范围,存储它的内存很可能被重用于其他目的。 返回的指针仍将指向局部变量曾经存在的内存位置,但由于该变量不再存在,该指针不会有多大用处。

还有一种方法可以做到..

 int mystruct(Mystruct *mystruct, int num, int size){ if(mystruct == NULL) return -1; mystruct->num = num; mystruct->size = size; :: return 0; } int main(){ Mystruct my; if(mystruct(&my, 3, 4) != 0){ fprintf(stderr, "Cannot init!\n"); exit(0); } :: }