继续介绍valgrind的使用, 看程序:
#include <stdio.h> #include <stdlib.h> #include <memory.h> int main() { char a[] = "abcdefghijk"; memcpy(a + 1, a, 5); printf("%s\n", a); return 0; } 先看看结果: [root@xxx ~/valgrind-3.8.1/bin]# g++ -g test.cpp [root@xxx ~/valgrind-3.8.1/bin]# ./a.out aaacdeghijk [root@xxx ~/valgrind-3.8.1/bin]# 啊? 怎么和预期的不一样? 原来, memcpy在拷贝的时候, 是不允许内存重叠的。 如果处理内存重叠的内存考虑, 我们应该用memmove. 看程序: #include <stdio.h> #include <stdlib.h> #include <memory.h> int main() { char a[] = "abcdefghijk"; memcpy(a + 1, a, 5); printf("%s\n", a); char b[] = "abcdefghijk"; memmove(b + 1, b, 5); printf("%s\n", b); return 0; } 结果为: [root@xxx ~/valgrind-3.8.1/bin]# g++ -g test.cpp [root@xxx ~/valgrind-3.8.1/bin]# ./a.out aaacdeghijk aabcdeghijk [root@xxx ~/valgrind-3.8.1/bin]# 用memmove就对了。
有时候, 在调试的时候, 会发现memcpy的上述诡异现象, 我们用valgrind来看看(针对如上第二个程序), 如下:
[root@xxx ~/valgrind-3.8.1/bin]# g++ -g test.cpp [root@xxx ~/valgrind-3.8.1/bin]# [root@xxx ~/valgrind-3.8.1/bin]# ./valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./a.out ==12994== Memcheck, a memory error detector ==12994== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al. ==12994== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info ==12994== Command: ./a.out ==12994== ==12994== Source and destination overlap in memcpy(0x7ff0004d1, 0x7ff0004d0, 5) ==12994== at 0x4C29A9E: memcpy (mc_replace_strmem.c:878) ==12994== by 0x40066C: main (test.cpp:8) ==12994== aabcdeghijk aabcdeghijk ==12994== ==12994== HEAP SUMMARY: ==12994== in use at exit: 0 bytes in 0 blocks ==12994== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==12994== ==12994== All heap blocks were freed -- no leaks are possible ==12994== ==12994== For counts of detected and suppressed errors, rerun with: -v ==12994== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6) [root@xxx ~/valgrind-3.8.1/bin]# 可以看到, 有内存重叠的问题。 下次我们用memcpy的时候, 也要小心才好。 涛歌依旧 认证博客专家 排名第一 点链接学人工智能 公众号免费领资料 ❤️零基础入门进阶人工智能 ❤️欢迎关注涛哥公众号,免费领海量学习资料。涛哥:毕业后就职于华为和腾讯。微信:ai_taogeyijiu