这是我的代码:我正在尝试获取结构的信息并深入复制信息.但是,valgrind
显示"无效阅读".我知道那是我读过发布的内存.我不知道为什么; 有人能够为我解决这个问题吗?
#include#include #include struct student { int id; char *name; int age; }; void get_info(struct student *dest, struct student *src) { memcpy(dest,src,sizeof(struct student)); dest->name = strdup(src->name); } int main() { struct student foo; foo.id = 1001; foo.name = strdup("kevin"); foo.age = 18; struct student bar; get_info(&bar, &foo); puts(bar.name); free(foo.name); free(bar.name); return 0; }
valgrind --tool=memcheck --leak-check=full ./test ==2130== Memcheck, a memory error detector ==2130== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==2130== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info ==2130== Command: ./test ==2130== ==2130== Invalid read of size 4 ==2130== at 0x40B083B: ??? (in /lib/tls/i686/cmov/libc-2.11.1.so) ==2130== by 0x40B04A4: strdup (in /lib/tls/i686/cmov/libc-2.11.1.so) ==2130== by 0x80484B1: get_info (test.c:15) ==2130== by 0x80484F8: main (test.c:26) ==2130== Address 0x419902c is 4 bytes inside a block of size 6 alloc'd ==2130== at 0x4026775: malloc (vg_replace_malloc.c:291) ==2130== by 0x40B04AF: strdup (in /lib/tls/i686/cmov/libc-2.11.1.so) ==2130== by 0x80484D8: main (test.c:22) ==2130== ==2130== Invalid read of size 4 ==2130== at 0x40B083B: ??? (in /lib/tls/i686/cmov/libc-2.11.1.so) ==2130== by 0x409ACE4: puts (in /lib/tls/i686/cmov/libc-2.11.1.so) ==2130== by 0x8048504: main (test.c:28) ==2130== Address 0x4199064 is 4 bytes inside a block of size 6 alloc'd ==2130== at 0x4026775: malloc (vg_replace_malloc.c:291) ==2130== by 0x40B04AF: strdup (in /lib/tls/i686/cmov/libc-2.11.1.so) ==2130== by 0x80484B1: get_info (test.c:15) ==2130== by 0x80484F8: main (test.c:26) ==2130== kevin ==2130== ==2130== HEAP SUMMARY: ==2130== in use at exit: 0 bytes in 0 blocks ==2130== total heap usage: 2 allocs, 2 frees, 12 bytes allocated ==2130== ==2130== All heap blocks were freed -- no leaks are possible ==2130== ==2130== For counts of detected and suppressed errors, rerun with: -v ==2130== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 11 from 6)
Jonathan Lef.. 6
我认为这实际上是一个valgrind
你应该压制的错误报告.它最终是您系统上C库中的一个错误.
抱怨的是,被调用的代码strdup()
在4个字节的偏移处读取4个字节,分成6个字节的块malloc()
.鉴于"kevin"
占用了6个字节,我相信一个memcpy()
变体已经被采用strdup()
并且已经被捕获在通过数据一次读取4个字节的行为中.虽然技术上可能实际上是安全的,但valgrind
抱怨是正确的.但是,您无法做任何事情 - 您的代码是无辜的,系统库是有罪的.这就是抑制的东西!
+---+---+---+---+---+---+...+...+ | k | e | v | i | n | \0| ? | ? | +---+---+---+---+---+---+...+...+
快速复制使用的是malloc()
'd数据是4字节(更可能是8字节)对齐的事实.它在一次操作中复制4个字节'k','e','v'和'i'; 然后它复制字符串的另外两个字节('n','\ 0')加上在第二个操作中技术上不属于分配空间的两个字节.在32位系统上,最小实际分配大概是8个字节; 它在64位机器上往往是16字节.这意味着额外的两个字节是为内存分配保留的空间的一部分,但valgrind
报告代码在分配的空间外复制是正确的.
我认为这实际上是一个valgrind
你应该压制的错误报告.它最终是您系统上C库中的一个错误.
抱怨的是,被调用的代码strdup()
在4个字节的偏移处读取4个字节,分成6个字节的块malloc()
.鉴于"kevin"
占用了6个字节,我相信一个memcpy()
变体已经被采用strdup()
并且已经被捕获在通过数据一次读取4个字节的行为中.虽然技术上可能实际上是安全的,但valgrind
抱怨是正确的.但是,您无法做任何事情 - 您的代码是无辜的,系统库是有罪的.这就是抑制的东西!
+---+---+---+---+---+---+...+...+ | k | e | v | i | n | \0| ? | ? | +---+---+---+---+---+---+...+...+
快速复制使用的是malloc()
'd数据是4字节(更可能是8字节)对齐的事实.它在一次操作中复制4个字节'k','e','v'和'i'; 然后它复制字符串的另外两个字节('n','\ 0')加上在第二个操作中技术上不属于分配空间的两个字节.在32位系统上,最小实际分配大概是8个字节; 它在64位机器上往往是16字节.这意味着额外的两个字节是为内存分配保留的空间的一部分,但valgrind
报告代码在分配的空间外复制是正确的.