Search code examples
cpointersmemorymalloccorruption

malloc(): memory corruption in a weird place


I've been dealing with an annoying memory corruption error for a couple of hours. I've checked every related thread here, and I couldn't fix it.

First of all, I'm writing a simple Terminal in C. I'm parsing the commands between pipe (|) and redirection (>, <, etc.) symbols and place them in the queue. Nothing complicated!

Here's the data structure for the queue;

struct command_node {
    int index;
    char *next_symbol;
    struct command_node *nextCommand;
    int count;
    char **args;
};

When I'm storing small strings in the **args pointer, everything works just fine. However, when one of the arguments is long, I get malloc(): memory corruption error. For example, the following 1st command works fine, the 2nd command causes the error

   1st:  ls -laF some_folder | wc -l

   2nd:  ls -laF /home/enesanbar/Application | wc -l

I run the debugger, it showed that the malloc() call for the new node in the queue causes the error.

newPtr = malloc( sizeof(CommandNode) );

I'm carefully allocating the array of strings and freeing after I'm done with them as follows:

    char **temp = NULL;
    temp = malloc(sizeof(char*) * number_of_args);

    /* loop through the argument array */
    for (i = 0; i < number_of_args; i++) {
        /* ignore the remaining commands after ampersand */
        if (strcmp(args[i], "&") == 0) return;

        /* split commands by the redirection or pipe symbol */
        if (!isSymbol(args[i])) {
            temp[count] = malloc(sizeof(strlen(args[i])) + 1);
            strcpy(temp[count], args[i]);
            count++;

            /* if it is the last argument, assign NULL to the symbol in the data structure */
            if (i + 1 == number_of_args) {
                insertIntoCommands(&headCommand, &tailCommand, temp, NULL, count);
                for (j = 0; j < count; j++) free(temp[j]);
                count = 0;  // reset the counter
            }

        }
        else {
            insertIntoCommands(&headCommand, &tailCommand, temp, args[i], count);
            for (j = 0; j < count; j++) free(temp[j]);
            count = 0;  // reset the counter
        }
    }

I must have missed something, or there's something I don't know about the **args fields and the allocation of the new node although it's nothing I haven't done before.


Solution

  • but how could wrapping a number around the sizeof cause an error in the allocation of a node? I'm just trying to understand out of curiosity.

    Like I was saying in my comment, you try to get the size of the pointer inside the strlen function and not the lenght which is provided through the function.

    Please take a look at the following:

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    
    
    int main(void){
        char *name = "Michi";
        size_t length1, length2;
    
        length1 = strlen(name);
        length2 =  sizeof strlen(name);
    
        printf("Length1 = %zu\n",length1);
        printf("Length2 = %zu\n",length2);
        return 0;
    }
    

    Output:

    Length1 = 5
    Length2 = 8
    

    One more thing, after you free(temp[j]) don't forget to free(temp) also.

    Something like this:

    #include <stdio.h>
    #include <stdlib.h>
    
    
    int main(void){
        long unsigned int size = 2,i;
        char **array;
    
        array = malloc(sizeof(char*) * size * size);
    
        if (array == NULL){
            printf("Error, Fix it!\n");
            exit(2);
        }
    
        for (i = 0; i < size; i++){
             array[i] = malloc(sizeof(char*) * 100);
        }
    
        /* do code here */
    
        for (i = 0; i < size; i++){
             free(array[i]);
        }
        free(array);
    
        return 0;
    }