Search code examples
cfreeclion

local variable may point to deallocated memory in C using CLion on Linux


I'm writing a project in C and I'm getting this warning

local variable may point to deallocated memory

for the following code

int printSched()
{
    char* schedString = (char*)malloc(strlen("cat /proc/sched\n")+sizeof(getppid()));
    if (schedString) {
        sprintf(schedString, "cat /proc/%d/sched\n", getppid());
        int commandSize = numOfWords(schedString);
        char** schedCommand = (char**) malloc((commandSize + 1) * sizeof (char*));
        if(schedCommand == NULL)
        {
            free(schedString);
            fprintf(stderr, "malloc failed");
            exit(1);
        }
        schedCommand[commandSize] = NULL;
        parseString(schedString, schedCommand);
        exeCommand(schedCommand);
        freeArr(schedCommand);
        return 0;
    }
    else //malloc failed - handled in main
        return -1;
}

about this particular free command

free(schedString);

I strognly believe that this message didn't appeared before the latest update of CLion to version 2021.1

Am I doing something wrong (atleast about this part) or it's a CLion problem?

numOfWords function

//receives a sentence and returns the number of words in it, ignoring blank spaces, assuming it ends with '\n'
int numOfWords(const char sentence[] )
{
    int i = 0, wordCounter = 0;
    while(sentence[i] != '\n')
    {
        if(sentence[i] != ' ' && (sentence[i+1] == ' ' || sentence[i+1] == '\n'))
            wordCounter++;
        i++;
    }
    return wordCounter;
}

Solution

  • I do not see a justification for "local variable may point to deallocated memory" with the posted code.


    Other problems may exist, yet I see this one:

    strlen("cat /proc/sched\n")+sizeof(getppid() may be too small.

    sizeof(getppid()) is the byte size of an pid_t and not its decimal string size.

    Better as

    #define INT_STR_MAXLEN 11
    strlen("cat /proc/sched\n") + INT_STR_MAXLEN + 1 /* \0 */)
    

    Even better as pid_t may be wider than an int. correct printf specifier for printing pid_t

    Call snprintf(NULL, 0,... to get the needed size.

    pid_t pid = getppid();
    int len = snprintf(NULL, 0, "cat /proc/%jd/sched\n", (intmax_t) pid);
    // assert(len > 0);
    
    char* schedString = malloc(len + 1);
    if (schedString) {
      sprintf(schedString, "cat /proc/%jd/sched\n", (intmax_t) pid);