我遇到了一個奇怪的情況,將一個指針傳遞給struct {}定義中定義的非常大的數組,這個數組大小約爲34MB。簡而言之,該僞代碼如下所示:奇怪的堆棧溢出?
typedef config_t{
...
float values[64000][64];
} CONFIG;
int32_t Create_Structures(CONFIG **the_config)
{
CONFIG *local_config;
int32_t number_nodes;
number_nodes = Find_Nodes();
local_config = (CONFIG *)calloc(number_nodes,sizeof(CONFIG));
*the_config = local_config;
return(number_nodes);
}
int32_t Read_Config_File(CONFIG *the_config)
{
/* do init work here */
return(SUCCESS);
}
main()
{
CONFIG *the_config;
int32_t number_nodes,rc;
number_nodes = Create_Structures(&the_config);
rc = Read_Config_File(the_config);
...
exit(0);
}
代碼編譯罰款,但是當我嘗試運行它,我會在下面{Read_Config_File()獲得一個SIGSEGV。
(gdb) run
...
Program received signal SIGSEGV, Segmentation fault.
0x0000000000407d0a in Read_Config_File (the_config=Cannot access memory at address 0x7ffffdf45428
) at ../src/config_parsing.c:763
763 {
(gdb) bt
#0 0x0000000000407d0a in Read_Config_File (the_config=Cannot access memory at address 0x7ffffdf45428
) at ../src/config_parsing.c:763
#1 0x00000000004068d2 in main (argc=1, argv=0x7fffffffe448) at ../src/main.c:148
我一直都在用小數組來完成這種事情。奇怪的是,0x7fffffffe448 - 0x7ffffdf45428 = 0x20B8EF8,或大約34MB的浮點數組。
Valgrind的會給我類似的輸出:
==10894== Warning: client switching stacks? SP change: 0x7ff000290 --> 0x7fcf47398
==10894== to suppress, use: --max-stackframe=34311928 or greater
==10894== Invalid write of size 8
==10894== at 0x407D0A: Read_Config_File (config_parsing.c:763)
==10894== by 0x4068D1: main (main.c:148)
==10894== Address 0x7fcf47398 is on thread 1's stack
錯誤信息都指向我重挫堆棧指針,但)我從來沒有穿過一個在函數的入口和崩潰運行B)我傳遞指針,而不是實際的數組。
有人可以幫我解決這個問題嗎?我在一個運行內核2.6.18和gcc 4.1.2的64位CentOS盒子上。
謝謝!
馬特
發佈僞代碼只會讓你僞造答案。魔鬼在細節中,他們可能都很重要。 –
我們可否看到'Read_Config_File'的來源?這就是問題出現的地方,在你消失的地方。 – Borealid
您不測試可能失敗的calloc()的返回值。 –