首页 > 解决方案 > 运行C程序时出现Segmentation Fault错误

问题描述

我是第一次使用 Valgrind 检查内存错误的新手。我正在运行 C 程序并看到与 C 程序无关的错误,但所有错误都来自内存(open64.c:48、_IO_file_open (fileops.c:189)、.....)。我不知道这些文件在哪里。你能帮我解决这个问题吗?

==40910== Memcheck, a memory error detector
==40910== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==40910== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==40910== Command: ./dd
==40910== 
==40910== Syscall param openat(filename) points to unaddressable byte(s)
==40910==    at 0x4ABCEAB: open (open64.c:48)
==40910==    by 0x4A3F195: _IO_file_open (fileops.c:189)
==40910==    by 0x4A3F459: _IO_file_fopen@@GLIBC_2.2.5 (fileops.c:281)
==40910==    by 0x4A31B0D: __fopen_internal (iofopen.c:75)
==40910==    by 0x4A31B0D: fopen@@GLIBC_2.2.5 (iofopen.c:86)
==40910==    by 0x109336: main (in /home/Desktop/dd)
==40910==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==40910== 
==40910== Invalid read of size 4
==40910==    at 0x4A317D7: fgets (iofgets.c:47)
==40910==    by 0x109427: main (in /home/Desktop/dd)
==40910==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==40910== 
==40910== 
==40910== Process terminating with default action of signal 11 (SIGSEGV)
==40910==  Access not within mapped region at address 0x0
==40910==    at 0x4A317D7: fgets (iofgets.c:47)
==40910==    by 0x109427: main (in /home/Desktop/dd)

==40910==  If you believe this happened as a result of a stack
==40910==  overflow in your program's main thread (unlikely but
==40910==  possible), you can try to increase the size of the
==40910==  main thread stack using the --main-stacksize= flag.
==40910==  The main thread stack size used in this run was 16777216.
==40910== 
==40910== HEAP SUMMARY:
==40910==     in use at exit: 984 bytes in 3 blocks
==40910==   total heap usage: 4 allocs, 1 frees, 1,456 bytes allocated
==40910== 
==40910== LEAK SUMMARY:
==40910==    definitely lost: 0 bytes in 0 blocks
==40910==    indirectly lost: 0 bytes in 0 blocks
==40910==      possibly lost: 0 bytes in 0 blocks
==40910==    still reachable: 984 bytes in 3 blocks
==40910==         suppressed: 0 bytes in 0 blocks
==40910== Rerun with --leak-check=full to see details of leaked memory
==40910== 
==40910== For lists of detected and suppressed errors, rerun with: -s
==40910== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)

标签: cmemory

解决方案


如果没有代码,这肯定是最容易回答的问题!

“不可寻址”=指向不属于你的字节。valgrind 警告您,因为您在内存中释放的内存可能不是您的(或者,至少,它不再保留用于您要求的用途),然后您可以将它用于另一件事并解释一个值不是。为什么在没有 valgrind 的情况下运行时它不会中断?好的,对于初学者来说 - 这就是你所说的。一方面,您的代码没有进行适当的错误检查。所以它可能会在里面破裂,所以你不会注意到它。我只能说糟糕的编码风格可能会编译和运行而不会显示任何错误,但在后台它可能会窒息它自己或它正在运行的东西。

地址 0x0 未堆栈、malloc 或(最近)free'd` 告诉您您正在取消引用 NULL 指针(地址 0x0 ...),这意味着 fopen 失败并返回 0/NULL。

尝试修复它?喜欢..

- 检查是否返回 fopen() 有效 FILE* 以避免尝试从 input_file 读取时出现未定义的行为。- 确保如果 fgets() 成功(不返回 NULL)以避免未定义的行为。

PS:阅读《C 程序员的 8 条诫命

2.不要跟随 NULL 指针,因为混乱和疯狂在等待着你。

6.如果一个函数被宣传为在遇到困难时返回一个错误代码,你应该检查那个代码,是的,即使检查是你的代码大小的三倍,并且在你的打字手指上产生疼痛,因为如果你认为“这不可能发生在我身上”,上帝一定会因你的傲慢而惩罚你。


推荐阅读