假设我有以下结构和函数返回一个指针:
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属性的属性吗?
答案 0 :(得分:36)
我应该声明一个Mystruct变量吗? 定义Mystruct的属性, 指定一个指针,然后返回 指针
绝对不是,因为函数中定义的变量(在“auto”存储类中)将在函数退出时消失,并且您将返回一个悬空指针。
您可以接受指向Mystruct
的指针(来电者有责任分配)并填写;或者,您可以使用malloc
创建一个新的(调用者有责任在完成后释放它)。第二个选项至少可以让你保持你似乎热衷的功能签名:
Mystruct *mystruct(int num, int size)
{
Mystruct *p = malloc(sizeof(MyStruct));
....
return p;
}
但它通常是次要的 - 因为调用者无论如何都必须承担责任,也可以使用第一个选项并可能获得性能(如果调用者可以使用自动类实例,因为它知道使用范围是有限的。)
答案 1 :(得分:7)
您无法使用该变量,因为在函数退出时将取消分配该变量。例如:
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;
}
答案 2 :(得分:3)
如果您正在编写通用代码而您不知道如何使用它,那么最好同时提供这两个选项:
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必须动态分配),但应该让应用程序编写者决定。
答案 3 :(得分:2)
分配一个新的Mystruct
并返回指向它的指针通常看起来或多或少是这样的:
Mystruct *mystruct(int num, int size)
{
Mystruct *result;
result = malloc(sizeof(MyStruct));
if (!result)
return NULL;
result->num = num;
...
return result;
}
稍后,当您使用Mystruct
完成此处分配的malloc
时,应该使用free()
再次释放它。
只是声明一个局部变量并返回一个指向该局部变量的指针将不起作用。局部变量超出了函数末尾的范围,存储它的内存很可能被重用于其他目的。返回的指针仍将指向本地变量曾经存在的内存位置,但由于该变量不再存在,该指针不会有多大用处。
答案 4 :(得分:2)
重要的是要记住,指针不是您分配给结构的东西,而是指针指示您希望将其视为结构的内存中的位置。根据您的问题,您确实希望分配内存来保存数据结构。这为您提供了指向已分配内存位置的指针。一旦你有了,你可以退货。
编辑(编辑原始问题后) 看看你对这个问题的编辑,你肯定会遇到“我的”指针问题。这是未初始化的,可能指向内存中的任何位置。当您尝试将结构复制到它时,您可能会遇到段错误。
答案 5 :(得分:2)
另一种方法......
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);
}
::
}