【发布时间】:2021-10-01 06:08:54
【问题描述】:
我有以下代码:
#include<stdio.h>
int main(void){
int x[20000000];
return 0;
}
将其编译为gcc file.c,并完美运行。
但是,将其编译为 gcc -fsanitize=address -fsanitize=undefined file.c 会出现以下错误:
AddressSanitizer:DEADLYSIGNAL
=================================================================
==364==ERROR: AddressSanitizer: stack-overflow on address 0x7fffcdbeb220 (pc 0x55b9a94951a0 bp 0x7fffce3ea220 sp 0x7fffcdbeb220 T0)
#0 0x55b9a949519f in main src/gbarray.c:3
#1 0x7efd3f2320b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
#2 0x55b9a94950cd in _start (/mnt/d/duart/Documents/personalProjects/Random/garbageArrayValue/bin/garbageArray+0x10cd)
SUMMARY: AddressSanitizer: stack-overflow src/gbarray.c:3 in main
==364==ABORTING
这里发生了什么,我该如何解决这个问题?
【问题讨论】:
-
栈大小有限,在堆上分配大数组。
-
局部变量通常放在栈上,包括数组。堆栈是有限资源,在 Windows 上只有一个 MiB,在 Linux 上标准堆栈大小为 8 MiB。您的阵列几乎是 80 MiB(使用常见的
sizeof(int) == 4)。 -
解释完了,这个大数组的目的是什么?很少需要这么大的阵列。如果您想存储大量数据,可能会有更好的数据结构或算法。
-
在the original question 中,数组是大小的十分之一(您错误地添加了零)并且它是
char的数组。这意味着大小仅略小于 2 MiB,而不是像您的阵列那样几乎 80 MiB。 :) -
如果没有 ASAN,数组中的内存永远不会被触及,所以即使它超过了堆栈空间,程序也可能不会崩溃(除非信号处理程序等)。将
x[0]=5;添加到您的程序中,看看有什么不同。 (另一方面,如果你启用优化,整个事情可能会被优化,因为它对程序的行为没有影响,所以崩溃会再次消失。)
标签: c gcc address-sanitizer