【问题标题】:Mac C program crashes on string initializerMac C 程序在字符串初始化程序上崩溃
【发布时间】: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


【解决方案1】:
extern short grid; // global outside the main
grid  = malloc(sizeof(short) *6000*6000) // inside the main.. 

您似乎正在使用多个文件..如果您使用任何标题,那么您也可以外部网格并在其他地方使用它..只有在我们看到实现后才能给出详细信息..此外,如果您使用的是 OSX,我建议您使用 lldb 而不是 gdb。因为 Mac 上的 gdb 可能存在代码签名问题

【讨论】:

    【解决方案2】:

    WhozCraig 明白了。 (见他的评论。)我试图在堆栈上分配比堆栈可以处理的更多。将数组移动到全局存储可以解决所有问题。

    【讨论】:

      猜你喜欢
      • 2015-06-25
      • 1970-01-01
      • 1970-01-01
      • 2016-05-30
      • 1970-01-01
      • 2016-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多