【问题标题】:valgrind sscanf issues with arguments [closed]valgrind sscanf 参数问题[关闭]
【发布时间】:2021-03-02 17:22:45
【问题描述】:

我在 c89 中编写这个程序来读取文件,但是我不断收到分段错误 我通过valgrind --leak-check=full --show-leak-kinds=all -v ./program 运行它,它指向两条 sscanf 行泄漏 运行程序,是两个文件名

./program cat.txt dog.txt 并遵守make文件 我已经释放它们并设置为空,但我仍然遇到这些问题,我附上了我的 [![valgrind errors here][1]][1]

的图片
int main(int argc, char* argv[]){

char* cat = (char*)malloc(12 * sizeof (char));
char* dog = (char*)malloc(12 * sizeof (char));
/*float sleepTime;*/

/*if (argc != 4)
{
    printf("Error - Enter file names");
}*/


sscanf(argv[1], "%s", cat);
sscanf(argv[2], "%s", dog);
sleepTime = atof(argv[3]);

readFile(cat);
readFile(dog);

free(cat);
free(dog);
cat = NULL;
dog = NULL;  

}

我试图将事情注释掉,但仍然没有运气 任何帮助将不胜感激

【问题讨论】:

  • 代码不完整。请提供minimal verifiable example - 包括所有缺失的代码、输入文件和用于运行程序的确切命令行。
  • 还请包括实际的 Valgrind 输出。
  • 对了,你这里使用动态分配的原因是什么?为什么不使用普通数组?
  • 另一方面,%[] 格式说明符就是 %[]。格式中没有s。除此之外,为什么还要在这里使用sscanf?命令行参数无论如何都不应该有换行符。
  • ./program 如果这确实是您调用程序的方式,那么它当然会出现段错误。没有命令行参数,在这种情况下 argv[1]argv[2] 将是未定义的值。

标签: c memory arguments valgrind


【解决方案1】:

好的,通过查看 valgrind 日志以及阅读您所写的内容,我收集了以下信息:

  1. 您正在使用生成文件进行构建,该文件应设置编译器参数 dog.txt 和 cat.txt,然后写入 catdog

  2. 调用 sscanf() 时,valgrind 日志在 main 中显示 Address 0x0 is not ...。 这意味着有一个空指针指向一个无效的内存地址,在sscanf() 调用中使用。

  3. 因此,要么 make 构建无法使用参数正确编译,要么 catdog 的内存分配不成功。

.

检查有效性: 我建议在调用 sscanf() 之前编写一些断言或编写函数来检查指针是否有效并调用它并检查您的指针,即 catdogargv[index]

https://ptolemy.berkeley.edu/~johnr/tutorials/assertions.html

https://wiki.sei.cmu.edu/confluence/display/c/MEM10-C.+Define+and+use+a+pointer+validation+function

来自上述链接的一个很好的简单的指针验证示例:

int valid(void *ptr) {
    return (ptr != NULL); // 1 valid, 0 invalid
}

为了解决最终的 makefile 问题,我认为我们需要查看有问题的 makefile,但如果由于某种原因无法完成,那么这些可能会引起您的兴趣:

Command-line arguments via Makefile

How to pass argument from Makefile to a program?

编辑:

我检查了有关问题的更新 valgrind 日志,并注意到 readFile() 中的可访问内存。 要解决该问题,您需要定义一个正确关闭文件的函数。由于您从不关闭文件,因此将它们挂在内存中会导致您的可访问内存警告。

【讨论】:

  • 我更改了一些代码并更新了 myvalgrind 代码
  • 重新阅读我的答案,因为它仍然适用。您应该特别阅读关于断言和指针验证的两个链接。如果您的指针验证显示您的 argv[1]、argv[2]、argv[3] 等于 NULL(这很可能),那么请阅读我的答案底部的两个链接,它们是相关的链接有好答案的问题
  • 使用来自其中一个链接的指针验证示例稍微更新了我的答案,希望它能让您清楚如何检查指针是否有效
  • 我检查了我的指针是否有效,它们都返回了 1
  • 一开始我没有注意到实际的 valgrind 日志已更新,我只是在答案底部进行了编辑,以修复可访问内存警告。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-25
  • 2017-06-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多