简体   繁体   中英

Using malloc to create an array of structs, will struct be created in each cell?

Suppose I have the following structs:

typedef struct plane_t Plane;
struct plane_t{
    Point p1;
    Point p2;
    Point p3;
};

typedef struct arrangement_t* Arrangement;
struct arrangement_t{
    //TODO add fields here
    int maxPlanes;
    int curPlanes;
    Plane *planes;
};

And I have the following function:

Plane planeCreate(Point point1, Point point2, Point point3){

    Plane newPlane = {{point1.x, point1.y, point1.z}, {point2.x, point2.y, point2.z}, {point3.x, point3.y, point3.z}};
    return newPlane;
}

Arrangement arrangementCreate(int maxPlanes){

    if (maxPlanes < 1) return NULL;

    Arrangment newArrangment = malloc(sizeof struct arrangement_t);
    if (newArrangment == NULL) return NULL;
    newArrangment->planes = malloc(sizeof(Plane)*maxPlanes);
    if (newArrangment->planes == NULL) {
        free(newArrangment);
        return NULL;
    }

    newArrangment->maxPlanes = maxPlanes;
    newArrangment->curPlanes = 0;

    return newArrangment;
}

Will the following line mean that every cell within the array will have a stuct of type Plane, or I still have to go over each cell in manually create them one by one? newArrangment->planes = malloc(sizeof(Plane)*maxPlanes);

malloc will allocate enough space for an array of maxPlanes structs, but it's up to you to initialize them.

In other words, if malloc succeeds, you will be able to access the structs newArrangement->planes[0] through newArrangement->planes[maxPlanes-1] . The structs are laid out end-to-end in memory as one contiguous block.

Your code is probably (see below) fine (by "fine" I mean functional, not well-designed). Your malloc(sizeof(Plane)*maxPlanes) will allocate space for maxPlanes planes, and you do not have to allocate each cell.

The cells themselves don't "have a struct of type Plane", it is merely a block of memory large enough to hold the information stored in maxPlanes Plane structs. Since you are accessing that block via a Plane pointer, the data will be interpreted as a Plane struct.

I say probably because your Plane struct members will be uninitialized (will contain random data), and since you don't show what a Point is, there is not enough information to know if what you have is sufficient. You also do not show what you are going to end up doing with the arrangement_t, so I presume that it is acceptable to leave the values uninitialized and that you are setting the values to something meaningful later.

I'd also make a number of recommendations to clarify your code:

  1. You typedef Arrangement as a pointer but Plane as a struct. I suggest perhaps qualifying your Arrangement type as ArrangementPtr or something instead to make the distinction and reduce confusion.

  2. Consider using calloc instead of malloc for clarity: calloc(maxPlanes, sizeof(Plane))

  3. If zeroing the memory is acceptable to you for initialization, you can do a quick memset(planes, 0, sizeof(Plane)*maxPlanes).

  4. Unless you have a specific reason to use C (there are many), you may wish to consider C++ (with STL classes if they are available to you), which will greatly reduce a lot of the work and possible sources of error in your code (note this is still not ideal because public members can break invariants that you may have, but just as an example):

struct Plane {
    Point p1;
    Point p2;
    Point p3;
    Plane ();
    Plane (const Point &, const Point &, const Point &);
};

struct Arrangement {
    int maxPlanes;
    int curPlanes;
    std::vector<Plane> planes;
    explicit Arrangement (int maxPlanes);
};

Plane::Plane () {
}

Plane::Plane (const Point &p1, const Point &p2, const Point &p3) :
    p1(p1), p2(p2), p3(p3)
{
}

Arrangement::Arrangement (int maxPlanes) :
    maxPlanes(maxPlanes),
    curPlanes(0),
    planes(maxPlanes)
{
}

That will handle all memory management for you; your job would be to catch std::bad_alloc to check for memory allocation errors, or add any necessary parameter validation.

Your code has a number of other problems, or potential for problems, but that's outside the scope of this question I think.

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