2016-04-30 103 views
-1

我有這樣一段代碼:空指針,內存分配和Valgrind的

void *data = calloc(1, sizeof(char)+sizeof(float)+sizeof(char)); // line 56 

*((char *) data) = 'a'; // line 58 
*((float *) data + sizeof(char)) = 0.2f; // line 59 
*((char *) data + sizeof(float) + sizeof(char)) = 'a'; // line 60 

printf("%c ", *((char *) data)); // line 62 
printf("%f ", *((float *) data + sizeof(char))); // line 63 
printf("%c ", *((char *) data + sizeof(float) + sizeof(char))); // line 64 
printf("\n"); 

而且basicly什麼,我試圖做的是保存在同一存儲區域不同類型的變量及其值。要做到這一點,我使用無效指針和變量的偏移量,一切工作正常,但是,valgrind不斷告訴我,我有無效的讀取和寫入,我不明白爲什麼。我認爲一切都很合理,但valgrind不同意。

這裏是Valgrind的輸出:

==5829== Memcheck, a memory error detector 
==5829== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. 
==5829== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info 
==5829== Command: ./a.out 
==5829== 
==5829== Invalid write of size 4 
==5829== at 0x400909: main (Main.c:59) 
==5829== Address 0x51f6044 is 4 bytes inside a block of size 6 alloc'd 
==5829== at 0x4C2AA98: calloc (vg_replace_malloc.c:711) 
==5829== by 0x4008ED: main (Main.c:56) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E83CEE: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E83ED6: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E7D9C0: __mpn_extract_double (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E843C9: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E83FFA: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E845E2: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Use of uninitialised value of size 8 
==5829== at 0x4E85504: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Use of uninitialised value of size 8 
==5829== at 0x4E7C2E8: __mpn_lshift (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E85508: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Use of uninitialised value of size 8 
==5829== at 0x4E7C2EB: __mpn_lshift (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E85508: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Use of uninitialised value of size 8 
==5829== at 0x4E85546: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E85568: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E856CC: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E85A54: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Use of uninitialised value of size 8 
==5829== at 0x4E7C904: __mpn_mul_1 (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E85A6F: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Use of uninitialised value of size 8 
==5829== at 0x4E7C98F: __mpn_mul_1 (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E85A6F: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Use of uninitialised value of size 8 
==5829== at 0x4E7CA02: __mpn_mul_1 (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E85A6F: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Use of uninitialised value of size 8 
==5829== at 0x4E85A83: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E85A92: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Use of uninitialised value of size 8 
==5829== at 0x4E7C3F8: __mpn_rshift (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E85DF1: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Use of uninitialised value of size 8 
==5829== at 0x4E7C41D: __mpn_rshift (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E85DF1: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Use of uninitialised value of size 8 
==5829== at 0x4E849F1: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Use of uninitialised value of size 8 
==5829== at 0x4E7C904: __mpn_mul_1 (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E849F8: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Use of uninitialised value of size 8 
==5829== at 0x4E7C928: __mpn_mul_1 (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E849F8: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E84A40: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Use of uninitialised value of size 8 
==5829== at 0x4E836D9: hack_digit (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E84A58: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Use of uninitialised value of size 8 
==5829== at 0x4E7C904: __mpn_mul_1 (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E836E0: hack_digit (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E84A58: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Use of uninitialised value of size 8 
==5829== at 0x4E7C928: __mpn_mul_1 (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E836E0: hack_digit (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E84A58: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E84A63: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E84A71: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E85093: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E85099: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E853BD: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E853E2: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E8541D: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E84BDF: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E84E36: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E84FF9: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E84FDB: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4EAFC4D: [email protected]@GLIBC_2.2.5 (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E85C90: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4EAFC7A: [email protected]@GLIBC_2.2.5 (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E85C90: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Conditional jump or move depends on uninitialised value(s) 
==5829== at 0x4E85C94: __printf_fp (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E82D9D: vfprintf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4E88D28: printf (in /usr/lib64/libc-2.22.so) 
==5829== by 0x400951: main (Main.c:63) 
==5829== 
==5829== Syscall param write(buf) points to uninitialised byte(s) 
==5829== at 0x4F27C10: __write_nocancel (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4EAE14E: [email protected]@GLIBC_2.2.5 (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4EAF8F8: [email protected]@GLIBC_2.2.5 (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4EAFD0A: [email protected]@GLIBC_2.2.5 (in /usr/lib64/libc-2.22.so) 
==5829== by 0x4EA6A47: putchar (in /usr/lib64/libc-2.22.so) 
==5829== by 0x40097A: main (Main.c:65) 
==5829== Address 0x4022004 is in a rw- anonymous segment 
==5829== 
a 0.199592 a 
==5829== 
==5829== HEAP SUMMARY: 
==5829==  in use at exit: 6 bytes in 1 blocks 
==5829== total heap usage: 1 allocs, 0 frees, 6 bytes allocated 
==5829== 
==5829== LEAK SUMMARY: 
==5829== definitely lost: 6 bytes in 1 blocks 
==5829== indirectly lost: 0 bytes in 0 blocks 
==5829==  possibly lost: 0 bytes in 0 blocks 
==5829== still reachable: 0 bytes in 0 blocks 
==5829==   suppressed: 0 bytes in 0 blocks 
==5829== Rerun with --leak-check=full to see details of leaked memory 
==5829== 
==5829== For counts of detected and suppressed errors, rerun with: -v 
==5829== Use --track-origins=yes to see where uninitialised values come from 
==5829== ERROR SUMMARY: 103 errors from 42 contexts (suppressed: 0 from 0) 

如果有人可以幫助我弄清楚爲什麼Valgrind的生氣將是巨大的。

非常感謝!

+4

如果您試圖實現數據局部性,您可以簡單地創建一個結構。如果您試圖爲多種類型使用變量,則應該使用聯合。如果你只是在嘗試,很酷,但這是生產代碼的一個可怕的想法。 – bodangly

+0

根據CPU的類型,它有對齊的問題。所以它不能直接用來從下一個字符點的地址直接取消引用大於char的數據。 – BLUEPIXY

回答

2

Valgrind很生氣,因爲你使用了錯誤的地址。

你的陳述全部使用指針算法,那就是不是整數運算

例如:

*((float *) data + sizeof(char)) 

將一個float尺寸偏移數據,而不是 「1」。

您需要正確的指針類型用於您的算術,並且在計算出正確的偏移量後,將其轉換爲您打算使用的類型。

+0

我很愚蠢。非常感謝兄弟! – PatriqDesigns