问题描述
有没有在编译时在gcc中启用内存管理的选项?
解决方案有没有在编译时在gcc中启用内存管理的选项?
解决方案在调试C时使用Valgrind的要点使用GCC编译的代码:使用-O0编译代码。 使用-O0编译代码。在一些比较罕见的情况下(例如内联汇编),您可能需要-O1。 从不使用更高的优化级别。编译器会严重破坏你的代码,以至于它可能使你的生活变得不可能。变量可以完全消失,函数可以在内联时离开,循环展开等等。基本上,除-O以外的任何其他操作都可能导致可执行代码与您的源代码很不相似。将符号调试到您的代码并且不要去除可执行文件。就像任何其他调试器一样,valgrind将使用可用的调试符号生成无限多的有用输出。它们将帮助valgrind将内存地址匹配到代码中的特定文件和行号,这是无价的。泄漏和许多其他问题我建议运行你的程序:
valgrind --log-file = valgrind.log --leak- check = full --track-origins = yes --show-reachable = yes ./program
然后请在valgrind.log文件中查找发现的任何问题。
编辑:
关于我建议的valgrind选项:
--log-file =告诉valgrind将它的输出发送到一个文件,我相信当你正在调试输出到控制台的程序时,发现了很多问题。
- leak-check = full告诉valgrind告诉您有关每个泄漏内存块的详细信息。
- track-origins = yes告诉valgrind找出未初始化的值来自哪里。它与内存泄漏没有任何关系,尽管它可以帮助处理其他问题。但是,它会让你的程序变得更慢,所以你可能希望删除这个选项,并且只在你跟踪未初始化的值时才添加它。
有一个--track-fds = yes选项可以帮助找到泄露的文件描述符,而不是只是内存。
一些程序员主张在程序结束时释放内存或关闭文件描述符,因为操作系统无论如何都会这样做。在那里是一个性能和代码大小的优势,恕我直言,这应该只能由有经验的程序员完成,并且应该通过删除生产版本的代码来完成,而不是从不写。编辑2:
一个重要的提示是:如果valgrind在你的代码中指出了一个问题,那么即使你的程序没有崩溃,它也可能是正确的。取决于结构对齐,内存分配器行为,平台,编译器版本和标志,或者月亮的相位,一些次要错误(例如读取缓冲器末尾的一个字节)可能保持不可见。如果您更改编译器,libc,平台或位数(例如,从64位变为32位),那么带有此类问题的代码可能会中断。
Is there any option for enabling no memory management in gcc while compiling?
Main points on using Valgrind while debugging C code compiled with GCC:
Compile your code using -O0. In some relatively rare cases (e.g. inline assembly) you may need -O1. Never use higher optimisation levels. The compiler will mangle your code so much that it can make your life impossible. Variables can disappear completely, functions can go mysteriously away as they get inlined, loops become unrolled and so on. Basically with anything other than -O0 you run the risk that the executable code will bear little resemblance to your source code.
Use the -g GCC option to add debugging symbols to your code and DO NOT strip the executables. Much like any other debugger, valgrind will produce infinitely more useful output with debugging symbols available. They will help valgrind match memory addresses to specific files and line numbers in your code which is invaluable.
To track memory leaks and many other problems I suggest running your program with:
valgrind --log-file=valgrind.log --leak-check=full --track-origins=yes --show-reachable=yes ./program
Then look in the valgrind.log file for any problems found.
EDIT:
About the valgrind options I suggested:
--log-file= tells valgrind to send its output to a file, which I believe can make things easier when you are debugging programs with output to the console, or when there are lots of issues found.
--leak-check=full tells valgrind to tell you details about each leaked memory block.
--track-origins=yes tells valgrind to find out where uninitialised values came from. It does not have anything to do with memory leaks, although it can help deal with other issues. It makes your program slower, though, so you might want to remove this option and add it only when you are tracking uninitialised values.
--show-reachable=yes tells valgrind to output memory blocks that have been allocated and not freed, even if there are still pointers to them at program exit. These blocks are not technically lost/leaked, since you still have pointers to them. Still, they can a) indicate a logic problem in your program (e.g. a list that grows indefinitely) b) they can and will become memory leaks if your main() becomes integrated as a function in another larger program. It would be best that there are no such issues left.
There is a --track-fds=yes option that can help find leaking file descriptors instead of just memory.
Some programmers advocate against freeing memory or closing file descriptors at program end, since the OS does that anyway. While there is a performance and code size advantage there, IMHO this should only be done by experienced programmers only, and it should be done by removing said code for the production release, rather than just never writing it. Otherwise, this encourages bad coding practices that should not be allowed.
EDIT 2:
One important hint: If valgrind indicates a problem in your code, it is most probably right, even if your program does not crash. Some "minor" errors (e.g. reading one byte past the end of a buffer) can remain unseen, depending on structure alignment, memory allocator behaviour, platform, compiler version and flags, or the phase of the moon. Code with such issues might just break if you change compiler, libc, platform or bitness (e.g. go from 64 to 32 bit).
这篇关于在gcc中不启用内存管理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!