【问题标题】:Segmentation fault depending on string length?分段错误取决于字符串长度?
【发布时间】:2011-01-10 02:32:10
【问题描述】:

我正在编写一个程序,它将使用 getline 从 infile 读取行到字符串,将字符串转换为包含字符串的前 m 个非空白字符的 c 字符串,然后将 c 字符串连接成单个 char 数组。

示例文件可能如下所示:

5    //number of rows and columns in a grid
2    //number of grids
XXXXX
XXXXX
XXXXX
XXXXX
XXXXX

XXXXX
XXXXX
XXXXX
XXXXX
XXXXX

所以我最终会得到一个 2x5x5 字符的 char 数组。 现在的问题是我的代码在上面显示的较小的测试用例上运行良好,但是当我在较大的网格(即 100x100x100)上尝试时出现分段错误。

#include <iostream>
#include <string>
using namespace std;
int main(){
  int mapsize,levels;
  cin>>mapsize;
  cin>>levels;
  char map[mapsize*mapsize*levels];
  string input;
  for (int i=0;i<levels;i++){
    for (int j=0;j<mapsize;j++){
      getline(cin,input);
      char *row;
      row=new char[input.size()+1];
      strcpy(row, input.c_str());
      for (int k=0;k<mapsize;k++){
        map[i*mapsize*mapsize+j*mapsize+k]=row[k];
      }
      delete [] row;
    }
  }
return 0;
}

我会用一个 infile 来调用这个程序: ./program

我已经使用 gdb 运行它并进行了回溯。 它总是指向“字符串输入;”这一行

有什么办法可以解决这个段错误吗? 谢谢

【问题讨论】:

  • 运行时数组大小不符合标准 C++。它符合 C99,这就是 gcc 允许它的原因。
  • 您应该为变量使用更好的名称,包括那些在循环中使用的名称。虽然i 在您有一个循环时是一个很好的名称,但当您有三个嵌套循环时,如果您给出正确的名称会更好:级别、行、列...另外,我不太明白为什么会这样您创建一个动态字符数组来转储字符串的内容,然后复制到地图...为什么不直接从字符串复制?

标签: c++ arrays string segmentation-fault getline


【解决方案1】:

map 是一个 VLA,分配在堆栈上,所以我猜你的问题是堆栈溢出。 gdb 指向 input 的构造,因为这是在溢出堆栈上构造的第一件事。

【讨论】:

  • 是的,100*100*100 是一个兆字节,这是大多数机器上的堆栈大小。请改用 malloc()。
【解决方案2】:

我不确定为什么回溯指向string input;,但是当您将row 复制到map 时。如果 mapsize 大于行的大小,您很可能最终会出现段错误。这对于更大的地图尺寸会更常见。

您也可能会踩踏堆栈上的返回地址,这可能会导致“错误”核心转储。

【讨论】:

    猜你喜欢
    • 2020-12-19
    • 2018-01-13
    • 1970-01-01
    • 1970-01-01
    • 2022-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多