我这里有一个简单的问题。我有一些变量声明如下:
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}
答案 0 :(得分:2)
您引用的警告消息显示无效的内存访问,这恰好击中了属于上述两个变量的内存区域。有问题的变量是错误的受害者,而不是犯罪者。变量不应该归咎于此。上述声明没有任何问题。这些声明很可能在这里没有任何相关性。
肇事者是main.c:253
和main.c:226
的行,您尚未引用这些行。这就是你的问题发生的地方。
一个疯狂的猜测是你在fill_PET_8day
(一个数组?)之后声明了另一个对象。使用其他对象时,会将其内存边界溢出约10个字节,从而破坏fill_PET_8day
和long_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=...
选项的大堆栈变量。