簡體   English   中英

讀取內存無效 - valgrind

[英]invalid read memory - valgrind

這是我的代碼:我正在嘗試獲取結構的信息並深入復制信息。 但是, valgrind顯示“無效讀”。 我知道那是我讀過發布的內存。 我不知道為什么; 有人能夠為我解決這個問題嗎?

#include  <stdlib.h>
#include  <stdio.h>
#include  <string.h>

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的報告

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)

我認為這實際上是valgrind的錯誤報告,你應該壓制。 它最終是您系統上C庫中的一個錯誤。

抱怨是從strdup()調用的代碼在4個字節的偏移處讀取4個字節到由malloc()分配的6個字節的塊中。 鑒於"kevin"占用了6個字節,我相信strdup()已經采用了memcpy()變體,並且已經捕獲了通過數據一次讀取4個字節的行為。 雖然它實際上可能是安全的,但在技術上, valgrind抱怨是正確的。 但是,您無法做任何事情 - 您的代碼是無辜的,系統庫是有罪的。 這就是抑制的東西!

+---+---+---+---+---+---+...+...+
| k | e | v | i | n | \0| ? | ? |
+---+---+---+---+---+---+...+...+

快速復制使用的事實是malloc() 'd數據是4字節(更可能是8字節)對齊的。 它在一次操作中復制4個字節'k','e','v'和'i'; 然后它復制字符串的另外兩個字節('n','\\ 0')加上在第二個操作中技術上不屬於分配空間的兩個字節。 在32位系統上,最小實際分配大概是8個字節; 它在64位計算機上往往是16字節。 這意味着額外的兩個字節是為內存分配保留的空間的一部分,但valgrind報告代碼正在分配的空間外復制是正確的。

這看起來像在一個優化strdup()puts()他們閱讀的四個字節,而不是每次一個字節塊他們的意見,但他們小心,不要超過年底。 只要四個字節的地址對齊,這是安全的:正確對齊的讀取永遠不會觸發硬件異常,並且由於這兩個函數不會寫入字符串的末尾,因此它們的操作是安全的,即使它是非法的語言觀點。 並且您可以確定這四個字節的地址將被正確對齊,因為它是一個優化,未對齊的讀取會使代碼爬行。

Valgrind檢查語言級別的正確性,而不是物理級別,因此檢查錯誤報告。 所以我同意Jonathan Leffler你應該壓制這個“錯誤”,看看評論,似乎是由更新版本的valgrind自動完成的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM