0

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;
}
RedYoel
  • 302
  • 2
  • 16
  • 1
    Just a note, there is [no need to cast `malloc`](https://stackoverflow.com/a/605858/14947044), because it's return type is `void *`, which is automatically and safely promoted to any other pointer type in C. – Andy Sukowski-Bang Apr 08 '21 at 15:21
  • It might not be looking at the `exit` at the end of the `if` block, so it's thinking if the `if` condition is true, you'll be using a pointer pointing to freed memory afterwards. – mediocrevegetable1 Apr 08 '21 at 15:23
  • @AndySukowski-Bang (detail) .... except for function pointers. (Works well with object pointers) – chux - Reinstate Monica Apr 08 '21 at 15:25
  • what's the signature/what's happening in `numOfWords`? Unless the argument is `const char*`, maybe it's raising the warning ..? – yano Apr 08 '21 at 15:31
  • 1
    Also, be careful with `malloc(strlen("cat /proc/sched\n")+sizeof(getppid()));`. `getppid()` returns a `pid_t` type. I don't know what that is, but its size is probably 4 or 8. The string representation of that number can be greater than 4 or 8, so there's possibility of overflowing `schedString` when you `sprintf(schedString, "cat /proc/%d/sched\n", getppid());` – yano Apr 08 '21 at 15:33
  • There has to be a _second_ `free` call that is the issue. Please _edit_ your question and post the entire function. A newer clion may have more comprehensive diagnostics. – Craig Estey Apr 08 '21 at 15:37
  • @CraigEstey I've edited and added what you asked for – RedYoel Apr 09 '21 at 05:54
  • @mediocrevegetable1 any suggestions for it? – RedYoel Apr 09 '21 at 05:55
  • @RedYoel unfortunately, I don't know. I've never used CLion anyway, that was just something I suspected. It may be correct, it may not be. I can't really say for sure. – mediocrevegetable1 Apr 09 '21 at 08:23
  • the lines of data/text in `proc/##/sched` end with a '\n' NOT a 'space'+'\n' – user3629249 Apr 10 '21 at 02:25

1 Answers1

2

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);
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256