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

时间:2011-10-05 05:36:33

标签: c memory-management struct malloc

假设我在ANSI C中有struct

typedef struct _point
{
    float x;
    float y;
} Point;

和此函数创建此struct

Point createpoint(float x, float y)
{
    Point p;
    p.x = x;
    p.y = y;
    return p; 
}

这允许我用这个函数创建一个struct,即:

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

    /* ...other stuff */

    return 0;
}

有人告诉我这段代码无效,因为structmalloc函数返回之前没有得到createpoint(float x, float y),并且struct将被删除。 但是,当我像这样使用struct时,它似乎不会被删除。

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

5 个答案:

答案 0 :(得分:14)

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

return p;
函数中的

返回局部变量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.

但是 -

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.

答案 1 :(得分:7)

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

答案 2 :(得分:5)

C99允许更好的堆叠式结构创建 鉴于以下结构

typedef struct
{
    float x;
    float y;
} Point;

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

Point p = (Point){0.4, 0.5};

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

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

答案 3 :(得分:3)

Point createpoint(float x, float y)
{
    Point p;
    p.x = x;
    p.y = y;
    return p; 
} /

函数中的所有局部变量都被删除after函数返回。

1> 通过引用传递 因此,如果要返回指向此局部变量的指针,则在函数返回后,将删除此变量,以使指针无效。

2 - ; 按值传递 但是这里你返回的是这个局部变量的副本,所以它是安全的,因为当函数返回时,局部变量是死的,但返回值的副本将在函数返回之前存储在函数调用的接收器变量中。

答案 4 :(得分:0)

对返回结构的方法的调用将表现得好像调用者在某个地方创建一个在任何其他范围内不可见的结构类型的临时变量,并为被调用函数提供指向它的指针。然后被调用的函数将数据放在请求的位置,并在它返回后,调用者将能够从其新变量中读取数据。给定一个函数和调用代码:

StructType BuildStruct(void)
{
  StructType it;
  it.this=4;
  it.that=23;
  return it;
}

StructType myStruct;
myStruct = BuildStruct();

如果不是两个,可能至少会有一个复制操作;语句return it;可能需要从本地变量it复制到临时结构,而myStruct的分配可能需要从临时位置复制到myStruct。没有情况实际上需要两个复制操作;有些需要一个(可以由调用者或被调用的方法执行),有些则不需要,但复制的必要性取决于调用者和被调用方法的细节。

另一种设计是:

void BuildStruct(StructType *it)
{
  it->this=4;
  it->that=23;
}

StructType myStruct;
BuildStruct(&myStruct);

这可能会产生相当于使用结构类型返回变量的最佳代码的代码,因为结构数据将被直接放入其最终位置而不需要任何结构复制。