开发者

ANSI C do you have to use malloc() when creating a struct?

Let's say I have this struct in ANSI C:

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

and this function to create this struct:

Point cre开发者_如何转开发atepoint(float x, float y)
{
    Point p;
    p.x = x;
    p.y = y;
    return p; 
}

This allows me to create a struct with this function i.e:

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

    /* ...other stuff */

    return 0;
}

Someone told me that this code is not valid, because the struct does not get malloc'd in the createpoint(float x, float y) function before it gets returned, and that the struct will be deleted. However, when I use my struct like this, it doesn't seem to get deleted.

So my question is: do I have to malloc this struct, and why? / why not?


Whatever you are doing is entirely correct. The statement -

return p;

in the function returns a copy of the local variable p. But if you want the same object that was created in the function, then you need to malloc it. However, you need to free it later.

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.

But -

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.


You can return struct on the stack, your code is valid. A problem would occur if you'd to return a pointer to the local variable, but that's not what you're doing, you're returning a copy, that's fine.


C99 allows for even nicer on-the-stack creation of structs.
Given the below struct

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

you can initialize it in a bit of a C++ constructor style manner with the following statement:

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

and thus you could either shorten your createpoint or scrap it altogether:

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


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

All local variables in function are deleted after function returns.

1> pass by reference So if you are returning pointer to this local variable then after function return this variables are deleted so that pointers are invalid.

2> pass by value But here you are returning copy of this local variable so its safe because that local variable are gona dead when function returns but the copy of return value will be stored in receiver variable in function call before function return.


A call to a method which returns a structure will behave as though the caller creates a temporary variable of the structure type somewhere which isn't visible in any other scope, and gives the called function a pointer to it. The called function will then put the data in the requested place, and after it returns the caller will be able to read the data from its new variable. Given a function and calling code:

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

StructType myStruct;
myStruct = BuildStruct();

it's likely that there will be at least one copy operation if not two; the statement return it; may need to copy from local variable it to the temporary struct, and the assignment to myStruct may need to copy from the temporary location to myStruct. No situation actually requires two copy operations; some require one (which could be performed by the caller or by the called method) and some require none, but the necessity of copying is dependent upon details in both the caller and the called method.

An alternative design would be:

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

StructType myStruct;
BuildStruct(&myStruct);

That would likely yield code equivalent to the best code one could hope for using a structure-type return variable, since the struct data would be placed directly into its final spot without any structure copying being necessary.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜