Search code examples
cdata-structuresmemory-managementrealloc

C assigning string to another string results in realloc(): invalid next size


I am trying to assign a string in a struct to the string of another struct:

func->parameters[func->parameter_amount].name = tokens[i+1].value;

this happens in a while loop:

while (true) {
    func->parameter_amount++;
    func->parameters = realloc(func->parameters, func-> parameter_amount*sizeof(struct parameter));
    if (func->parameters == NULL) {
        mem_error();
    }
    if ((tokens[i].token != symbol) && (tokens[i].token != comma)) {
        break;
    } else if ((tokens[i].token == symbol) && tokens[i+1].token == symbol) {
        func->parameters[func->parameter_amount].type = string_to_type(tokens[i].value);
        if (func->parameters[func->parameter_amount].type == -1) {
            printf("Error: Invalid type '%s' for parameter declaration in function '%s' on line %i\n", tokens[i].value, func->name, func->line);
            exit(1);
        }
        func->parameters[func->parameter_amount].name = tokens[i+1].value;
        i += 2;
    } else if (tokens[i].token == comma) {
        func->parameter_amount--;
        i++;
    }
}

after the assignment happens the program says: realloc(): invalid next size and aborts

the structures are defined as:

struct parameter {
    int type;
    char* name;
};

struct function {
    int line;
    int type;
    char* name;
    struct parameter* parameters;
    int parameter_amount;
};

typedef struct {
    int token;
    char* value;
    int line;
} token;

I can't figure out whats going wrong


Solution

  • There are multiple bugs in your code:

    1) After realloc, the size of func->parameters array is func->parameterAmount. So that means that the last index you can use func->parameterAmount-1:

    func->parameters[func->parameterAmount - 1]
    

    2) For every element in func->parameters array, you have to allocate the string value (because at that moment value is just a pointer to a character):

    int i = 0;
    int n = 129; // n will be the max length (minus 1) of newly allocated string
    for (i = 0; i < func->parameterAmount; ++i) {
        func->parameters[i].name = (char *) malloc(sizeof(char) * n);
        if (func->parameters[i].name == NULL) {
          // Handle alloc error
        }
    } 
    

    Also, remember to allocate all string variables value inside token array.

    3) In C, you can't assign a value to a string that way. You have to use strcpy() from string.h header:

    strcpy(func->parameters[func->parameter_amount].name, tokens[i+1].value);