Thyldor
Thyldor

Reputation: 53

Issues with structure variable initialization

For some reason my struct variable doesn't reliably hold its values

I've tried designated initializers and doing it "manually" in a separate function. The odd thing is, it works for one variable, but doesn't for another.

struct triangle;

struct vertex{
    int tag;
    double x;
    double y;
    int isBorder; //0 if it isn't, 1 if it is
};

struct edge{
    struct vertex *a;
    struct vertex *b;
    struct triangle *triangle1;
    struct triangle *triangle2;
    int refinementOrder;
    int isBorder; // 0 false, 1 true
    int isOdd; //0 false; 1 true

};

struct triangle{ 
    struct vertex *vertex1;
    struct vertex *vertex2;
    struct vertex *vertex3;
    struct edge *edge1;
    struct edge *edge2;
    struct edge *edge3;
    struct triangle *neighbour1;
    struct triangle *neighbour2;
    struct triangle *neighbour3;
    int type; //0 - even/a ; 1 - odd/b
};

struct edge *newE1, *newE2 = {0}, *newE3;

newE1 = malloc(sizeof(newE1));
newE2 = malloc(sizeof(newE2));
newE3 = malloc(sizeof(newE3));

*newE1 = (struct edge) {v1, com, NULL, NULL, refinementOrder+1, 0, 0};
*newE2 = (struct edge) {v2, com, NULL, NULL, refinementOrder+1, 0, 0};
//initEdge(newE2, v2, com, refinementOrder+1);
*newE3 = (struct edge) {v3, com, NULL, NULL, refinementOrder+1, 0, 0};
//newE2->isBorder = 0;
printf("%d\n", newE2->isBorder);

Even though I initialize newE2 with 0 in isBorder, the print statement gives me something that looks like a memory address. The odd thing is, it does give 0 if I try newE1. It also gives me 0 if I manually assign it 0 in this function. If I manually assign it 0 in a separate function (done in initEdge(...) it doesn't print 0.

Upvotes: 0

Views: 58

Answers (2)

Thyldor
Thyldor

Reputation: 53

It was just bad malloc-ing. I was malloc-ing space for a pointer, not the struct.

Using malloc(sizeof(*newE1)) fixed the issues.

Upvotes: 0

dbush
dbush

Reputation: 225344

You're not allocating enough space for your sturctures:

newE1 = malloc(sizeof(newE1));
newE2 = malloc(sizeof(newE2));
newE3 = malloc(sizeof(newE3));

The variables newE1 is a pointer, so sizeof(newE1) gives you the size of a pointer, not what it points to (and the same for newE2 and newE3). Pointers are typically either 4 or 8 bytes in size, so this is most likely less than the size of the struct.

As a result, when you attempt to write to particular members of the struct, you write past the end of the allocated memory block. This invokes undefined behavior.

To allocate the proper amount of memory:

newE1 = malloc(sizeof(*newE1));
newE2 = malloc(sizeof(*newE2));
newE3 = malloc(sizeof(*newE3));

Note also the use of sizeof(*newE1) instead of sizeof(struct edge), as this is more resilient in the event the name of the struct changes or is replaced with a typedef.

Upvotes: 1

Related Questions