C语言 返回结构指针

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2702928/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:16:44  来源:igfitidea点击:

Returning a struct pointer

cpointersstruct

提问by idealistikz

Suppose I have the following struct and function returning a pointer:

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

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;
}

I want to define any Mystruct pointer using the above function. Should I declare a Mystruct variable, define the properties of Mystruct, assign a pointer to it, and return the pointer or define the properties of a mystruct property through a pointer immediately?

我想使用上述函数定义任何 Mystruct 指针。我应该声明一个 Mystruct 变量,定义 Mystruct 的属性,为其分配一个指针,然后返回该指针还是立即通过一个指针定义一个 mystruct 属性的属性?

回答by Alex Martelli

Should I declare a Mystruct variable, define the properties of Mystruct, assign a pointer to it, and return the pointer

我是否应该声明一个 Mystruct 变量,定义 Mystruct 的属性,为其分配一个指针,然后返回该指针

Definitely not, because the variable defined in the function (in "auto" storage class) will disappear as the function exits, and you'll return a dangling pointer.

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

You could accepta pointer to a Mystruct(caller's responsibility to allocate that) and fill it in; or, you can use mallocto create a new one (caller's responsibility to free it when it's done). The second option at least lets you keep the function signature you seem to be keen on:

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

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

but it's often an inferior one -- since the caller has to have responsibilities anyway, may as well go with the first option and potentially gain performance (if the caller can use an auto-class instance because it knows the scope of use is bounded).

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

回答by staticman

You can't use the variable because it will be deallocated when the function exits. For example:

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

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

Will give a segmentation fault or access violation because the memory for x is deallocated as soon as you exit. So you have to allocate memory for the struct (and be sure to free it up later) or declare a global that will stay around for ever. Example for the latter...

将给出分段错误或访问冲突,因为 x 的内存在您退出时立即被释放。因此,您必须为结构分配内存(并确保稍后将其释放)或声明一个将永远存在的全局变量。后者的例子...

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

回答by R Samuel Klatchko

If you are writing generic code and you don't know how it may be used, it's good to provide both options:

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

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;
}

The idea is that as a library writer, you shouldn't dictate policy (such as that each Mystruct must be dynamically allocated) but should let the application writer decide that.

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

回答by N 1.1

One more way to do it..

另一种方法来做到这一点..

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);
   }
   ::
}

回答by sth

Allocating a new Mystructand returning a pointer to it would usually look more or less like this:

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

Mystruct *mystruct(int num, int size)
{
   Mystruct *result;

   result = malloc(sizeof(MyStruct));
   if (!result)
     return NULL;

   result->num = num;
   ...

   return result;
}

Later, when you are done with the Mystructallocated here with malloc, it should be freed again with free().

稍后,当您完成Mystruct此处分配的 with 时malloc,应再次使用 将其释放free()

Just declaring a local variable and returning a pointer to that local variable will not work. The local variable goes out of scope at the end of the function and the memory where it was stored is most likely reused for other purposes. The returned pointer will still point to the memory location where the local variable once was, but since that variable doesn't exist anymore, that pointer wouldn't be of much use.

仅仅声明一个局部变量并返回一个指向该局部变量的指针是行不通的。局部变量在函数结束时超出范围,并且存储它的内存很可能被重用于其他目的。返回的指针仍将指向局部变量曾经所在的内存位置,但由于该变量不再存在,该指针将没有多大用处。

回答by graza

It's important to remember that the pointer is not something you assign to the structure, but rather the pointer indicates the location in memory that you wish to treat as a structure. Based on your question, you really want to allocate the memory to hold the data structure. This gives you a pointer to the memory location allocated. Once you have that, you can return it.

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



EDIT(after edit to original question) Looking at your edit to the question, you definitely will have problems with the "my" pointer. This is uninitialised, and may point to anywhere in memory. When you attempt to copy the structure to it, you'll probably get a seg-fault.

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