C变量初始化valgrind抱怨

时间:2015-08-06 16:27:10

标签: c variables initialization valgrind

我这里有一个简单的问题。我有一些变量声明如下:

char long_name_VARA[]="TEST -- Gridded 450m daily Evapotranspiration (ET)";
int16 fill_PET_8day=32767;

鉴于上述valgrind抱怨char声明如下:

Invalid write of size 8
==21902==    at 0x408166: main (main.c:253)
==21902==  Location 0x7fe677840 is 0 bytes inside long_name_VARA[0]

和int16声明如下:

==21902== Invalid write of size 2
==21902==    at 0x408178: main (main.c:226)
Location 0x7fe677420 is 0 bytes inside local var "fill_PET_8day"

我在这里的声明中做错了什么?

我也不能声明像这样的char数组:

char temp_year[5]={0}

3 个答案:

答案 0 :(得分:2)

您引用的警告消息显示无效的内存访问,这恰好击中了属于上述两个变量的内存区域。有问题的变量是错误的受害者,而不是犯罪者。变量不应该归咎于此。上述声明没有任何问题。这些声明很可能在这里没有任何相关性。

肇事者是main.c:253main.c:226的行,您尚未引用这些行。这就是你的问题发生的地方。

一个疯狂的猜测是你在fill_PET_8day(一个数组?)之后声明了另一个对象。使用其他对象时,会将其内存边界溢出约10个字节,从而破坏fill_PET_8daylong_name_VARA的前8个字节。这就是valgrind警告你的事情。

答案 1 :(得分:0)

如上所述,声明不是问题。

虽然仅供参考,但将常量字符串声明为const ...

可能更好
const char* long_name_VARA = "TEST -- Gridded 450m daily Evapotranspiration (ET)";

甚至......

const char* const long_name_VARA = "TEST -- Gridded 450m daily Evapotranspiration (ET)";

这可以防止在代码(和指针)中修改字符串。

答案 2 :(得分:0)

当我运行以下

/* test.c */
#include <stdio.h>

int main(void)
{
    char s[8000000];
    int x;

    s[0] = '\0';
    x=5;
    printf("%s %d\n",s,x);
    return 0;
}

与Valgrind我得到了

$ gcc test.c
$ valgrind ./a.out
==1828== Memcheck, a memory error detector
==1828== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==1828== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==1828== Command: ./a.out
==1828== 
==1828== Warning: client switching stacks?  SP change: 0xfff0002e0 --> 0xffe85f0d0
==1828==          to suppress, use: --max-stackframe=8000016 or greater
==1828== Invalid write of size 1
==1828==    at 0x400541: main (in /home/m/a.out)
==1828==  Address 0xffe85f0d0 is on thread 1's stack
==1828==  in frame #0, created by main (???)
==1828== 
==1828== Invalid write of size 8
==1828==    at 0x400566: main (in /home/m/a.out)
==1828==  Address 0xffe85f0c8 is on thread 1's stack
==1828==  in frame #0, created by main (???)
==1828== 
==1828== Invalid read of size 1
==1828==    at 0x4E81ED3: vfprintf (vfprintf.c:1642)
==1828==    by 0x4E88038: printf (printf.c:33)
==1828==    by 0x40056A: main (in /home/m/a.out)
==1828==  Address 0xffe85f0d0 is on thread 1's stack
==1828==  in frame #2, created by main (???)
==1828== 
 5
==1828== Invalid read of size 8
==1828==    at 0x4E88040: printf (printf.c:37)
==1828==    by 0x40056A: main (in /home/m/a.out)
==1828==  Address 0xffe85f0c8 is on thread 1's stack
==1828==  in frame #0, created by printf (printf.c:28)
==1828== 
==1828== Warning: client switching stacks?  SP change: 0xffe85f0d0 --> 0xfff0002e0
==1828==          to suppress, use: --max-stackframe=8000016 or greater
==1828== 
==1828== HEAP SUMMARY:
==1828==     in use at exit: 0 bytes in 0 blocks
==1828==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==1828== 
==1828== All heap blocks were freed -- no leaks are possible
==1828== 
==1828== For counts of detected and suppressed errors, rerun with: -v
==1828== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)

如果我给Valgrind选项警告我得到

$ valgrind --max-stackframe=10000000 ./a.out
==1845== Memcheck, a memory error detector
==1845== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==1845== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==1845== Command: ./a.out
==1845== 
 5
==1845== 
==1845== HEAP SUMMARY:
==1845==     in use at exit: 0 bytes in 0 blocks
==1845==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==1845== 
==1845== All heap blocks were freed -- no leaks are possible
==1845== 
==1845== For counts of detected and suppressed errors, rerun with: -v
==1845== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

所以“无效的读/写”是由于没有正确的--max-stackframe=...选项的大堆栈变量。