【发布时间】:2015-09-20 19:26:52
【问题描述】:
我正在尝试在我的 Mac 上构建别人的 C 程序,使用命令行工具构建命令行程序。直截了当的 C 程序,应该和任何东西一样简单。但是在 main() 中的变量声明和初始化期间,我遇到了非常奇怪的内存访问错误,太早了,我真的不明白我怎么会搞砸任何事情。这是基本的核心 C 语言材料,它怎么会失败真的让我感到震惊。
Ken$ gcc -std=c99 -ggdb srtm2stl.c geometry.c stlwriter.c -o srtm2stl
Ken$ gdb ./srtm2stl
. . .
(gdb) run
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x00007fff5b74f6c0
0x0000000100000e37 in main (argc=10, argv=0x7fff5fbff990) at srtm2stl.c:195
195 char SolidName[132] = {' '}; // Optional name for solid (text format STL files)
(gdb) list 195
190 int main(int argc, char *argv[])
191 {
192 FILE *in = NULL; // input file
193 FILE *out = NULL; // output file
194
195 char SolidName[132] = {' '}; // Optional name for solid (text format STL files)
196 // char SolidName[132]; // Optional name for solid (text format STL files)
197 int Verbose = 0; // Flag: Verbose
唯一想到的是它是在 64 位模式下构建的,而我之前从未构建过 64 位程序。是否需要为 gcc 提供其他命令行参数才能使其正常工作?还是其他理论?
注意第 196 行。如果我注释掉第 195 行并改用第 196 行,我们会在类似的崩溃之前走得更远:
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x00007fff5b74f8e0
main (argc=1, argv=0x7fff5fbffa20) at srtm2stl.c:216
216 unsigned int i = 0;
(gdb) list 216
214 long Bias = 0;
215 short grid[MAXROWS][MAXCOLS]; // Array to hold the elevations
216 unsigned int i = 0;
217 short stemp;
似乎有一些关于数组的东西。 MAXROWS 和 MAXCOLS 在这个版本中都是 6001,这不应该被现代内存大小压倒。对吧?
OSX 10.7.5,gcc 版本 i686-apple-darwin10-llvm-gcc-4.2, GNU gdb 6.3.50-20050815
【问题讨论】:
-
6001 * 6001 * sizeof(short) = 68.7 MB 的连续自动内存(读取:堆栈),假设 16 位短。我一点也不惊讶这东西不能运行。是的,它势不可挡。自动存储!=免费存储空间。动态分配更有可能奏效。或者将
grid移动到全局;您的电话。 -
您几乎肯定会溢出堆栈。 6000*6000*2 = ~70MB。我对 MAC 环境一无所知,但我猜它太大而无法放入堆栈。
-
尝试在堆中动态添加内存,它会起作用..这是一个堆栈内存溢出问题..我不知道您正在编译的代码的人是如何编译他的代码的.. ..这会给任何机器带来问题.. 8MB 是最大堆栈限制.. 不超过..
-
是的,WhozCraig,就是这样。我继承的程序使用 1201*1201*sizeof(short),它很大但很合适,我把它推得太远了。将阵列移动到全局存储解决了所有问题。我很沮丧,我必须在运行时学习这一点,似乎编译时警告非常合适。
标签: c macos command-line 64-bit