2012-12-29 44 views
0

我的程序遇到了這個小問題。在Visual Studio 2012中它運行良好,但如果我使用G ++編譯它(是的,出於上述原因,我必須使用它來編譯),錯誤信號11(SIGSEGV)或6(SIGABRT)會根據輸入而被觸發。這是一個編程練習,我有另一個程序(在線服務器上),它用10個不同的輸入測試我的程序。正如我所說的,該程序在使用Visual Studio 2012時編譯和運行良好。由信號11(SIGSEGV)和/或6(SIGABRT)殺死

關於該程序: 它找到從起點(x,y)到出口數的最短路徑(出口量不相關不同,可能只有一個出口或可能有200個出口)。 輸入變如下:

7 12   // maze height and width 
##########.# // 
#..........# // 
#.###.###### // 
#..X#.#..... // the maze blueprint 
#.###.#.#### // 
#..........# // 
############ // 

而且我的程序:

#include <iostream> 
#include <vector> 

typedef struct _laby_t { 
    int h, w; 
    char **pohja; // 'pohja' is finnish and means layout 
} laby_t; 

typedef std::vector<int> monovector; 
typedef std::vector< std::vector<int> > bivector; 

laby_t *laby_allocate (int r, int c) 
{ 
    laby_t *laby; 
    int i; 

    laby = new laby_t[sizeof (laby_t)]; 
    laby->pohja = new char *[r]; 
    for (i = 0; i < r; i++) 
    { 
     laby->pohja[i] = new char[c]; 
    } 
    laby->h = r; 
    laby->w = c; 

    return laby; 
} 

int wander(int y, int x, laby_t *&_laby, int goals) 
{ 
    laby_t *laby = _laby; 
    int found = 0, depth = 0, min_path = 1000000; 
    bool b = 0; 
    bivector openList; 
    monovector start; start.push_back(y); start.push_back(x); 
    bivector closedList; 

    openList.push_back(start); 

    while(found < goals) 
    { 

     y = openList.back()[0]; x = openList.back()[1]; 
     monovector r; r.push_back(y); r.push_back(x); closedList.push_back(r); 
     openList.pop_back(); 
     if(laby->pohja[y][x] != '*') laby->pohja[y][x] = '-'; 
     depth++; 

     if(y == 0 || y+1 == laby->h || x == 0 || x+1 == laby->w) { 
      found++; 
      if(depth < min_path) min_path = depth; 
      if(found >= goals) { 
       std::cout << min_path << std::endl; 
       break; 
      } 
      laby->pohja[y][x] = '-'; 

      goto back_track; 
     } 
     else 
     { 
      b = 0; 
      if(laby->pohja[y+1][x ] == '.') { monovector r; r.push_back(y+1); r.push_back(x); openList.push_back(r); b=1; } 
      if(laby->pohja[y ][x+1] == '.') { monovector r; r.push_back(y); r.push_back(x+1); openList.push_back(r); b=1; } 
      if(laby->pohja[y-1][x ] == '.') { monovector r; r.push_back(y-1); r.push_back(x); openList.push_back(r); b=1; } 
      if(laby->pohja[y ][x-1] == '.') { monovector r; r.push_back(y); r.push_back(x-1); openList.push_back(r); b=1; } 
      if(!b) 
      { 
back_track:  while(closedList.size() > 0) 
       { 
        //std::cout << closedList.size() << std::endl; 
        int c_y = closedList.back()[0]; int c_x = closedList.back()[1]; 
        int o_y = openList.back()[0]; int o_x = openList.back()[1]; 

        laby->pohja[y][x] = '*'; 

        y = c_y; x = c_x; 

        laby->pohja[y][x] = '*'; 

        if((c_y+1 == o_y && c_x == o_x) || 
         (c_y == o_y && c_x+1 == o_x) || 
         (c_y-1 == o_y && c_x == o_x) || 
         (c_y == o_y && c_x-1 == o_x)) 
        { 
         laby->pohja[y][x] = '-'; 
         y = o_y; x = o_x; 
         closedList.pop_back(); 
         depth--; 
         break; 
        } 
        else { 
         closedList.pop_back(); 
         depth--; 
        } 
       } 
      } 
     } 
    } 

    return min_path; 
} 

int main() 
{ 
    int h, w, goals = 0; 
    std::cin >> h >> w; 

    laby_t *laby; 
    laby = laby_allocate(h, w); 

    for(int i = 0; i < laby->h; i++) 
     std::cin >> laby->pohja[i]; 

    for(int i = 1; i < laby->h-1; i++) { 
     if(laby->pohja[i][0] == '.') goals++; 
     if(laby->pohja[i][laby->w-1] == '.') goals++; 
    } 

    for(int i = 1; i < laby->w-1; i++) { 
     if(laby->pohja[0][i] == '.') goals++; 
     if(laby->pohja[laby->h-1][i] == '.') goals++; 
    } 

    for(int i = 0; i < laby->h; i++) 
     for(int j = 0; j < laby->w; j++) { 
      if(laby->pohja[i][j] == 'X') { 
       wander(i, j, laby, goals); 
       goto _exit; 
      } 
     } 

_exit: 

    //system("pause"); 
    return 0; 
} 

我已經做了我關於errorsignals功課,萬一你們不知道這件事情:http://www.yolinux.com/TUTORIALS/C++Signals.html

提前致謝。

+0

您的第一步應該是編譯調試信息並調試代碼,以便至少知道哪一行會導致您的問題。 – Neil

回答

1

此行溢出您的內存分配。如果用戶輸入w字符,則需要(w + 1)字符來保存以空字符結尾的字符串。

std::cin >> laby->pohja[i]; 

這行也分配了許多laby_t對象的數組,雖然你似乎只想要一個。也許你把C++ new與C malloc搞混了。

laby = new laby_t[sizeof (laby_t)]; 

您可以用它替換它。

laby = new laby_t; 

這也似乎是下的殘餘這是不是一個錯誤,但它不必要的污染與reduntant符號的當前命名空間。

typedef struct _laby_t { ... } laby_t; 

您可以用此替換它。

struct laby_t { ... }; 
+0

我對結構有點不熟悉,所以只要我的調試器不出現繁榮,我也不會注意到:D分配也是:我必須複製使用malloc的代碼片段,但是因爲它沒有執行g ++我必須放棄並嘗試另一種方式。謝謝!很有幫助。我會盡快回到家中看到我的代碼。 –

3

代碼完全編譯在Mac OS X 10.7.5與G ++ 4.7.1,這是好的:

g++ -g -Wall -Wextra laby.cpp -o laby 

不幸的是,當該結果爲valgrind下運行時,其產生:

==15030== Invalid write of size 1 
==15030== at 0x306BE: std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char> >(std::basic_istream<char, std::char_traits<char> >&, char*) (in /usr/lib/libstdc++.6.0.9.dylib) 
==15030== by 0x10000117D: main (laby.cpp:113) 
==15030== Address 0x10001632c is 0 bytes after a block of size 12 alloc'd 
==15030== at 0xB823: malloc (vg_replace_malloc.c:266) 
==15030== by 0x5768D: operator new(unsigned long) (in /usr/lib/libstdc++.6.0.9.dylib) 
==15030== by 0x576DA: operator new[](unsigned long) (in /usr/lib/libstdc++.6.0.9.dylib) 
==15030== by 0x1000008C0: laby_allocate(int, int) (laby.cpp:21) 
==15030== by 0x100001146: main (laby.cpp:110) 

因此,laby_allocate()函數中的內存分配存在問題。或幾個...

laby_t *laby_allocate (int r, int c) 
{ 
    laby_t *laby; 
    int i; 

    laby = new laby_t[sizeof (laby_t)]; 

該行分配一個數組laby_t;它將在陣列中分配儘可能多的元素,因爲laby_t中有字節。這不是你需要的。

laby = new laby_t; 

繼續:

laby->pohja = new char *[r]; 
    for (i = 0; i < r; i++) 
    { 
     laby->pohja[i] = new char[c]; 
    } 

這並不在數據...這就是爲什麼「寫」是1個字節的結尾零分配足夠的空間。更改cc+1valgrind提供了一個乾淨的健康法案。

laby->h = r; 
    laby->w = c; 

    return laby; 
} 

給出的答案是15;我不相信這是正確的。

+0

啊!是的,分配還不是我最強烈的一點。當我回到家時,我會看到我的代碼。 –