Search code examples
cmemorymemory-managementlinked-listnodes

Would there be memory overflow when using linked list with nodes in C? And does it happen usually?


I'm working on a programming exercise which concentrates on the use of linked list in C, and this is how I defined a node struct and some functions to work with it:

typedef struct log{
    struct log* next;
    long time;
    int status;
    char plate[];
}log;
log* init_lg(long t, int st, char pl[])
{
    log* p = (log*)malloc(sizeof(log));
    p->time = t; p->status = st; strcpy(p->plate, pl);
    p->next = NULL;
    return p;
}
void ins_lg(long t, int st, char pl[])
{
    if (lg == NULL)
    {
        lg = init_lg(t, st, pl);
        return;
    }
    log* i = lg;
    while (i->next != NULL) i = i->next;
    i->next = init_lg(t, st, pl);
}

However, I find out that the ins_lg function can't work properly with the pl[] string argument having the length of more than 7.

I can't reduce the size of that pl[] argument as its length must be higher than 7 due to the input data, sadly. So would there be a good solution for this?

For example, I tried that with pl[] being "1234567" and it ran well, but when I changed the pl[] into "12345678", it seemed falling into a frozen state and gave out an process-returning code of -1073740940 after a quite long delay.

I thought the problem might only be memory overflow, as I tested all the functions and they worked well with shorter (and smaller of course) values for the arguments.


Solution

  • The plate member has no size specified. Given that it's the last member of a struct, that makes it a flexible array member.

    Such a member doesn't actually have any space put aside for it, so malloc(sizeof(log)) doesn't allocate any space for this member. This means that any write to plate is writing past the end of allocated memory, triggering undefined behavior.

    You would need to allocate enough space for the string you want to store in addition to the struct itself:

    log* p = malloc(sizeof(log) + strlen(pl) + 1);