c - 空指针、内存分配和 valgrind

标签 c pointers heap-memory void-pointers

我有这段代码:

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"); 

基本上我想做的就是在同一内存区域中保存各种类型的变量及其值。为此,我使用 void 指针和变量偏移量,一切正常,但是,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: _IO_file_overflow@@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: _IO_file_overflow@@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: _IO_file_write@@GLIBC_2.2.5 (in /usr/lib64/libc-2.22.so)
==5829==    by 0x4EAF8F8: _IO_do_write@@GLIBC_2.2.5 (in /usr/lib64/libc-2.22.so)
==5829==    by 0x4EAFD0A: _IO_file_overflow@@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 如此生气,那就太好了。

非常感谢!

最佳答案

Valgrind 很生气,因为您使用了错误的地址。

您的语句都使用指针算术,而不是整数算术

例如:

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

向数据添加一个 float 大小的偏移量,而不是“1”。

您的算术需要正确的指针类型,计算出正确的偏移量后,转换为您想要使用的类型。

关于c - 空指针、内存分配和 valgrind,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36960923/

相关文章:

c - 如何将分隔的字节复制到 double 变量中?

C 未定义对 InetPtonW 的引用

c - 在线编译器是否在其服务器上生成 a.out/exe 文件?

c - 当exe文件没有资源部分时,向exe文件添加图标

c++ - 将指针或对象放入类中?

c - 为什么这段代码(指向单个变量的两个指针)显示段错误?

c - SPARC 程序集,如何访问指向结构的 C 指针

c++ - 如何删除堆中未存储到变量指针的对象?

winapi - malloc 和 HeapAlloc 之间是否有根本区别(除了可移植性)?

android - 如何增加 Android 2.3 (Gingerbread) 上的堆大小?