返回结构指针

ide*_*ikz 22 c struct pointers

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

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;
}
Run Code Online (Sandbox Code Playgroud)

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

Ale*_*lli 36

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

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

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

Mystruct *mystruct(int num, int size)
{
   Mystruct *p = malloc(sizeof(MyStruct));
   ....
   return p;
}
Run Code Online (Sandbox Code Playgroud)

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

  • 在C语言中没有必要(并且在该语言中通常被认为是不好的风格) - 但在C++中则相反. (5认同)

sta*_*man 7

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

Mystruct *mystruct(int num, int size)
{
   MyStruct x;
   x.num = 1;
   ...
   return &x;
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • 实际上`return*x`将不会在第一个函数中编译(我猜你的意思是'return&x`?******会给出你认为的更微妙的错误,或更可能是偶数 - 错误的错误). (2认同)

R S*_*hko 5

如果您正在编写通用代码并且不知道如何使用它,最好提供两个选项:

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;
}
Run Code Online (Sandbox Code Playgroud)

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