实例介绍利用valgrind定位memcpy内存重叠问题------顺便再次说说memcpy和memmove的区别
2017-03-12 19:25
579 查看
继续介绍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的时候, 也要小心才好。
#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的时候, 也要小心才好。
相关文章推荐
- 实例介绍利用valgrind定位内存非法访问问题
- 实例介绍利用valgrind定位内存异常释放问题(double free 和wrong free)
- memmove 和 memcpy的区别以及处理内存重叠问题
- 实例介绍利用valgrind定位变量未初始化的问题
- memmove 和 memcpy的区别以及处理内存重叠问题
- memmove 和 memcpy的区别以及处理内存重叠问题
- 实例介绍利用valgrind定位内存泄漏问题
- memmove 和 memcpy的区别以及处理内存重叠问题
- memmove 和 memcpy的区别以及处理内存重叠问题
- memmove 和 memcpy的区别以及处理内存重叠问题
- 实例介绍利用valgrind定位内存泄漏问题
- 实例介绍利用valgrind定位strcpy/strncpy/strcat/strncat内存重叠问题
- memcpy memmove区别和实现(如何处理内存重叠问题)
- memcpy 内存重叠问题
- strcpy,memcpy,memmove和内存重叠分析
- 常见内存拷贝函数:memcpy()、memmove()、strcpy()的实现及区别
- oom和oom-killer实例简介(内存用完和进程杀死)------顺便说说linux下的两个重要目录:/proc/kmsg和/var/log/messages
- 话说linux 下的pthread 内存问题 (Valgrind 检测 及定位排除)
- C\C++内存重叠问题,memcpy,memmov,strcpy
- C内存重叠问题,memcpy,memmov,strcpy