2010-01-27 81 views
1

我正在編寫一個程序,它將使用getline將字符串讀取到字符串中,將字符串轉換爲包含字符串的前m個非空白字符的c字符串,然後將c字符串連接成單個字符數組。根據字符串長度分段錯誤?

樣本文件可能是這個樣子:

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

XXXXX 
XXXXX 
XXXXX 
XXXXX 
XXXXX 

所以我想最終的2x5x5字符的字符數組。 現在的問題是我的代碼在像上面顯示的那樣的小測試情況下工作正常,但是當我在更大的網格上嘗試時出現了分段錯誤(即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 < infile.in

我用gdb運行它,並做了回溯。 它始終指向「字符串輸入」行;

任何想法如何解決這個段錯誤? 謝謝

+3

運行時數組大小不符合C++標準。它符合C99,這就是gcc允許的原因。 – doron 2010-01-27 19:01:32

+0

您應該爲變量使用更好的名稱,包括循環中使用的名稱。當你有一個循環時'i'是一個好名字,當你有三個嵌套循環時,如果你給出了正確的名字會更好:level,row,col ...另外,我不太明白爲什麼它你創建一個動態字符數組轉儲字符串的內容,然後複製到地圖......爲什麼不直接從字符串中複製? – 2010-01-27 19:17:05

回答

7

map是一個VLA,分配在堆棧上,所以我猜你的問題是你得到一個堆棧溢出。 gdb指向input的構造,因爲這是在這個溢出堆棧上構建的第一個東西。

+0

是的,100 * 100 * 100是兆字節,大多數機器上的堆棧大小。使用malloc()代替。 – 2010-01-27 19:03:36

+0

謝謝!這非常有幫助。 – zebraman 2010-01-27 19:07:42

+3

有趣的是,他們會在這個網站之後提出錯誤。 – 2010-01-27 19:24:56

2

我不確定爲什麼回溯指向string input;,但是當您將row複製到map時。如果mapsize大於行的大小,那麼最終可能會導致seg-faulting。這對更大的地圖更爲常見。

你也可能跺腳堆棧上的返回地址可能導致「錯誤的」核心轉儲。