【问题标题】:local variable may point to deallocated memory in C using CLion on Linux在 Linux 上使用 CLion 的局部变量可能指向 C 中已释放的内存
【发布时间】:2021-07-04 12:00:01
【问题描述】:

我正在用 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;
}

【问题讨论】:

  • 请注意,这里有no need to cast malloc,因为它的返回类型是void *,它会自动安全地提升为C语言中的任何其他指针类型。
  • 它可能没有查看if 块末尾的exit,因此它在考虑if 条件是否为真,您将使用指向释放的指针事后记忆。
  • @AndySukowski-Bang (detail) .... 函数指针除外。 (适用于对象指针)
  • 签名是什么/numOfWords 中发生了什么?除非参数是const char*,否则它可能会引发警告......?
  • 另外,请注意malloc(strlen("cat /proc/sched\n")+sizeof(getppid()));getppid() 返回 pid_t 类型。我不知道那是什么,但它的大小可能是 4 或 8。该数字的字符串表示可能大于 4 或 8,因此当您 sprintf(schedString, "cat /proc/%d/sched\n", getppid()); 时,schedString 可能会溢出

标签: c free clion


【解决方案1】:

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


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

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

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

更好

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

更好的是pid_t 可能比int 更宽。 correct printf specifier for printing pid_t

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

【讨论】:

    猜你喜欢
    • 2021-12-20
    • 2012-12-28
    • 1970-01-01
    • 2011-02-10
    • 2014-09-05
    • 2010-09-16
    • 1970-01-01
    • 2012-10-12
    • 1970-01-01
    相关资源
    最近更新 更多