首页 > 解决方案 > 在 Linux 上使用 CLion 的局部变量可能指向 C 中已释放的内存

问题描述

我正在用 C 编写一个项目,我收到了这个警告

局部变量可能指向释放的内存

对于以下代码

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;
}

关于这个特定的免费命令

free(schedString);

我坚信在 CLion 最新更新到 2021.1 版本之前没有出现此消息

我做错了什么(至少关于这部分)还是 CLion 问题?

numOfWords 函数

//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;
}

标签: cfreeclion

解决方案


我没有看到发布代码的“局部变量可能指向已释放内存”的理由。


可能存在其他问题,但我看到了这个:

strlen("cat /proc/sched\n")+sizeof(getppid()可能太小了。

sizeof(getppid())是 an 的字节大小,pid_t而不是它的十进制字符串大小。

不如

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

甚至更好,因为pid_t可能比int. 用于打印 pid_t 的正确 printf 说明符

致电snprintf(NULL, 0,...获得所需的尺寸。

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);

推荐阅读