ANSI C在创建结构时是否必须使用malloc()?

Mar*_* R. 15 c malloc struct memory-management

假设我struct在ANSI C中有这个:

typedef struct _point
{
    float x;
    float y;
} Point;
Run Code Online (Sandbox Code Playgroud)

这个函数来创建这个struct:

Point createpoint(float x, float y)
{
    Point p;
    p.x = x;
    p.y = y;
    return p; 
}
Run Code Online (Sandbox Code Playgroud)

这允许我创建一个struct具有此功能,即:

int main()
{
    Point pointOne = createpoint(5, 6);  
    Point pointTwo = createpoint(10, 4);
    float distance = calculatedistancefunc(pointOne, pointTwo);

    /* ...other stuff */

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

有人告诉我这段代码无效,因为在返回之前它struct没有malloccreatepoint(float x, float y)函数中获取,并且struct将被删除.但是,当我使用我struct这样的时候,它似乎没有被删除.

所以我的问题是:我必须malloc这样做struct,为什么?/ 为什么不?

Mah*_*esh 15

无论你做什么都是完全正确的.该声明 -

return p;
Run Code Online (Sandbox Code Playgroud)

在函数中返回局部变量的副本p.但是如果你想要在函数中创建的相同对象,那么你需要malloc它.但是,您需要free稍后再做.

Point createpoint(float x, float y)
{
    Point p;
    p.x = x;
    p.y = y;
    return p; 
} // p is no longer valid from this point. So, what you are returning is a copy of it.
Run Code Online (Sandbox Code Playgroud)

但是 -

Point* createpoint(float x, float y)
{
    Point *p = malloc(sizeof(Point));
    p->x = x;
    p->y = y;
    return p; 
}// Now you return the object that p is pointing to.
Run Code Online (Sandbox Code Playgroud)

  • @YassineHoussni - 因为您阅读代码的次数可能比编写代码的次数多,所以代码可读性比编码更舒适更重要.如果你将内存分配和释放保存在同一个块中,那么泄漏内存将更加困难,因为资源只保留在需要它们的确切时间内,并且每次重新设置(即:`malloc()`/`getmem() `/`new`)与disallocation(`free()`/`freemem()`/`delete`)在视觉上配对.你可以很容易地发现一个没有`delete`的`new`,但是你会发现`createpoint()`而不是`delete`吗?维护程序员会这样做吗? (4认同)

lit*_*adv 8

您可以struct在堆栈上返回,您的代码有效.如果你要返回一个指向局部变量的指针会出现问题,但这不是你正在做的事情,你要返回一个副本,那没关系.

  • 但是如果您使用更大的结构执行相同的过程,则应该关心内存使用情况,因为在返回时会复制每个字段.在那个特定的情况下,这不应该是一个问题. (2认同)
  • @ Marnixv.R.传递值基本上复制了值.这对于小变量(如整数)来说很好,但是对于结构,特别是大结构,创建副本是浪费的.通过引用意味着您引用现有变量,而不是将其复制到新变量中. (2认同)

Rus*_*hPL 5

C99允许更好的堆栈创建结构.
鉴于以下结构

typedef struct
{
    float x;
    float y;
} Point;
Run Code Online (Sandbox Code Playgroud)

您可以使用以下语句以一些C++构造函数样式方式初始化它:

Point p = (Point){0.4, 0.5};
Run Code Online (Sandbox Code Playgroud)

因此,您可以缩短创建点或完全废弃它:

int main()
{
    Point pointOne = (Point){5, 6};
    Point pointTwo = (Point){10, 4};
    float distance = calculatedistancefunc(pointOne, pointTwo);
    //...other stuff
    return 0;
}
Run Code Online (Sandbox Code Playgroud)