简体   繁体   中英

How to allocate memory for a structure with a pointer to an array of structures in C?

I have a function which create and return a new object for a list, but I'm having troubles with allocation of memory (Error: core dumped). I figured it's because of '*model', which is a pointer to an array for structures. I'm quite new to dynamic memory allocation and not sure what and how to allocate the right amount of memory.

Function:

// Return a newly created object based on the arguments provided. 
object_t *create_object(SDL_Surface *surface, triangle_t *model, int numtriangles)
{
    // Allocate memory for a new object
    object_t *new_obj = malloc(sizeof(object_t));
        if (new_obj == NULL)
            return NULL;
    // Allocate memory for the model array
    triangle_t *arrayPtr = malloc((sizeof(triangle_t))*numtriangles);
        if (arrayPtr == NULL)
            return NULL;

    // Assign values
    arrayPtr = model;
    new_obj->model = arrayPtr;
    new_obj->numtriangles = numtriangles;
    new_obj->surface = surface;
    // Return created object
    return new_obj;
}

Function call in main:

object_t *ball = create_object(surface, sphere_model, SPHERE_NUMTRIANGLES);

Structures:

typedef struct object object_t;
struct object {
    float       scale;
    float       rotation;
    float       tx, ty;
    float       speedx, speedy;
    unsigned int ttl;          
    int         numtriangles;
    triangle_t  *model;
    SDL_Surface *surface;
};

typedef struct triangle triangle_t;
struct triangle {
    int x1, y1;
    int x2, y2;
    int x3, y3;
    unsigned int fillcolor;
    float scale;
    int tx, ty;
    float rotation;
    SDL_Rect rect;
    int sx1, sy1;
    int sx2, sy2;
    int sx3, sy3;
};

Array:

#define SPHERE_NUMTRIANGLES    478   // <-- Array size
triangle_t sphere_model[] = {
{
.x1=-1,
.y1=-500,
.x2=-1,
.y2=-489,
.x3=-1,
.y3=-500,
.fillcolor=0xeeeeee,
.scale=1.0
},
{
.x1=-1,
.y1=-489,
.x2=-1,
.y2=-500,
.x3=40,
.y3=-489,
.fillcolor=0xbb0000,
.scale=1.0
},
...

I tried object_t *new_obj = malloc(sizeof(object_t) + (sizeof(triangle_t)*numtriangles)); but with no success.

// Assign values
arrayPtr = model;

What you do here is discard newly allocated pointer contained in arrayPtr, and just assign it to point to the same memory as model . It might crash if model has shorter lifetime (eg allocated on stack) and is no longer valid pointer after function returns.

I believe your intention here was to copy content from model array into your new array, so you should have done something like:

memcpy(arrayPtr, model, (sizeof(triangle_t))*numtriangles);

So, looks like object_t *new_obj = malloc(sizeof(object_t) + (sizeof(triangle_t)*numtriangles)); is an unnecessarily large allocation.

I say this because this line in the create_object method arrayPtr = model; is assigning the memory address of the passed-in triangle_t* 'model', to the newly allocated arrayPtr.

However, on the line above this you allocated a load of memory to the arrayPtr address... This would therefore lead to a memory leak as you are allocating the memory to that address, and then changing the address of the pointer (so it no longer points at that memory) but you aren't calling free on that memory, so it will sit on the heap for the duration of your program.

With the line arrayPtr = model; I suspect what you actually want to do is perform a memory copy of the contents of the model address, to the newly allocated arrayPtr address. This should therefore actually look like:

memcpy(arrayPtr, model, sizeof(triangle_t) * numTriangles);

Sadly I am unable to run your code as I am at work without access to a C compiler however, I would suspect that your error is caused by you free'ing the memory of the 'model' pointer that is still being accessed by the object_t struct due to the accidental misuse of the '=' assignment operator.

Thanks for the help. My thought process was to assign a pointer enough memory for the array, then make a copy of set array by assigning it to the pointer.

Anyway, this did did the trick:

new_obj->model = malloc(sizeof(triangle_t)*numtriangles);
    if (new_obj == NULL)
        return NULL;
bcopy(model, new_obj->model, sizeof(triangle_t)*numtriangles);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM