如何使用C语言中的结构数组指针为结构分配内存?

时间:2018-11-09 08:59:58

标签: c arrays struct nested dynamic-memory-allocation

我有一个为列表创建并返回新对象的函数,但是我在分配内存时遇到了麻烦(错误:核心已转储)。我认为这是因为'* model',它是指向结构数组的指针。我对动态内存分配还很陌生,不知道该如何分配以及如何分配适当数量的内存。

功能:

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

主函数调用:

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

结构:

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

数组:

#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
},
...

我尝试了object_t *new_obj = malloc(sizeof(object_t) + (sizeof(triangle_t)*numtriangles));,但没有成功。

3 个答案:

答案 0 :(得分:2)

// Assign values
arrayPtr = model;

您在这里要做的是丢弃arrayPtr中包含的新分配的指针,然后将其分配为指向与model相同的内存。如果model的生存期较短(例如,在堆栈上分配),并且在函数返回后不再是有效的指针,则可能会崩溃。

我相信您的意图是将模型数组中的内容copy放入新数组中,因此您应该执行以下操作:

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

答案 1 :(得分:2)

因此,看来object_t *new_obj = malloc(sizeof(object_t) + (sizeof(triangle_t)*numtriangles));是不必要的大分配。

之所以这样说,是因为create_object方法arrayPtr = model;中的这一行正在将传入的triangle_t *'model'的内存地址分配给新分配的arrayPtr。

但是,在此行上方,您为arrayPtr地址分配了一个内存负载...因此,当您将内存分配给该地址,然后更改指针的地址时,这将导致内存泄漏(因此它不再指向那个内存),但是您不会在该内存上调用free,因此它将在程序执行期间位于堆上。

用行arrayPtr = model;,我怀疑您实际上想要执行的操作是将模型地址的内容的内存副本复制到新分配的arrayPtr地址。 因此,实际上应该如下所示:

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

可悲的是,我无法在不访问C编译器的情况下运行代码,但是,我怀疑您的错误是由您释放仍在访问的“模型”指针的内存引起的由于意外误用了'='赋值运算符而由object_t结构造成的。

答案 2 :(得分:0)

感谢您的帮助。 我的思想过程是为指针分配足够的内存,然后通过将其分配给指针来复制set数组。

无论如何,这确实起到了作用:

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