0

I was trying to allocate memory using malloc, I am not able to understand why I am getting a different result for these two malloc calls.

The line below gives me wrong result even though with gdb I see the data is getting the correct value assigned.

  • nodeptr n = malloc(sizeof(nodeptr));

    Value head->data: '!'
    Value head->eq->data: ''

And when I do this get the correct result:

  • nodeptr n = malloc(sizeof(struct Node));

    Value head->data: 'w'
    Value head->eq->data: 'X'

I followed this post, I think I am doing it correctly.
In both ways, while allocation I get the same amount of memory, just I see the different results in the end.

typedef struct Node
{
    struct Node *left, *right, *eq;
    char data;
    bool isEnd;
} *nodeptr;

nodeptr newNode(const char c) {
    nodeptr n = malloc(sizeof(nodeptr));
    // nodeptr n = malloc(sizeof(struct Node));
    n->data = c;
    n->left = NULL;
    n->right = NULL;
    n->left = NULL;
    n->isEnd = false;

    return n;
}

void insert(nodeptr *node, const char *str) {

    if (*node == NULL) {
        *node = newNode(*str);
    }
    nodeptr pCrawl = *node;

    if(pCrawl->data < *str) {
        insert(&pCrawl->right, str);
    } else if (pCrawl->data > *str) {
        insert(&pCrawl->left, str);
    } else {
        if(*(str+1)) {
            insert(&pCrawl->eq, str + 1);
        } else {
            pCrawl->isEnd = true;
        }
    }
}

int main(int argc, char const *argv[])
{

    const char* const strs[5]= {
        "w.",
    };
    nodeptr head = NULL;
    for(int i = 0; i<1; i++) {
        insert(&head, strs[i]);
    }
    return 0;
    printf("Value head->data: \'%c\'\n", head->data);
    printf("Value head->eq->data: \'%c\'\n", head->eq->data);
}
3
  • 1
    Note that the newNode() function does not initialize the eq member of the structure. It should. Commented Jul 15, 2019 at 4:35
  • regarding; nodeptr n = malloc(sizeof(nodeptr)); This will allocate enough memory for a pointer. (4 or 8 bytes, depending on underlying hardware and certain compiler options) So writing anything as an offset from that pointer is undefined behavior. Commented Jul 15, 2019 at 22:50
  • 2
    OT: Do not hide pointers via typedefs Commented Jul 15, 2019 at 22:50

2 Answers 2

3

sizeof(nodeptr) == sizeof(struct Node*) != sizeof(struct Node) == sizeof(*nodeptr)

  • sizeof(nodeptr) will always be the size of a pointer (like 8 bytes on a 64-bit CPU)
  • sizeof(struct Node) refers to the struct contents
  • sizeof(*nodeptr) is equivalent to sizeof(struct Node) with the extra dereference operator in there.

The reason it may appear to "work" (not segfault) is that malloc suballocates from a larger block of heap memory. However, the code is writing out-of-bounds of the requested allocation, which can eventually lead to heap corruption or segfaults at some point.

Sign up to request clarification or add additional context in comments.

Comments

3

The two different versions aren't allocating the same amount of memory. sizeof(nodeptr) is the size of a pointer and sizeof(struct Node) is the size of your struct. These are not the same things and they're not the same size. On my computer these values are 8 and 32.

You want to use:

nodeptr n = malloc(sizeof(struct Node));

or perhaps:

nodeptr n = malloc(sizeof(*n)); // size of the type that n points too

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.