Убит по сигналу 11 (SIGSEGV) и / или 6 (SIGABRT)

У меня небольшая проблема с моей программой. В Visual Studio 2012 он работает нормально, но если я скомпилирую его с помощью G ++ (да, по указанным выше причинам, я должен использовать его для компиляции), сигналы ошибки 11 (SIGSEGV) или 6 (SIGABRT) сработают в зависимости от ввода , Это упражнение по программированию, и у меня есть другая программа (на онлайн-сервере), которая тестирует мою программу с 10 различными входами. Как я уже сказал, программа компилируется и хорошо работает при использовании Visual Studio 2012.

О программе:
Он находит кратчайший путь от начальной точки (x, y) до количества выходов (количество выходов не имеет значения и различается. Может быть только 1 выход или может быть 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;
}

Я сделал свою домашнюю работу, связанную с ошибочными сигналами, и если вы, ребята, не знаете об этом: http://www.yolinux.com/TUTORIALS/C++Signals.html

Заранее спасибо.

1

Решение

Код компилируется чисто на 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 байт. Изменить c в c+1 а также valgrind дает чистый счет здоровья.

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

return laby;
}

Ответ дан 15; Я не уверен, что это правильно.

4

Другие решения

Эта строка переполняет ваше выделение памяти. Если пользователь вводит вес персонажи, то (W + 1) символы будут необходимы для хранения строки с нулевым символом в конце.

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

Эта строка также выделяет массив из многих laby_t объекты, хотя вы, кажется, хотите только один. Возможно, вы перепутали C ++ new с С malloc,

laby = new laby_t[sizeof (laby_t)];

Вы можете заменить это этим.

laby = new laby_t;

Это также кажется остатком C. Это не ошибка, но она излишне загрязняет текущее пространство имен избыточными символами.

typedef struct _laby_t { ... } laby_t;

Вы можете заменить это этим.

struct laby_t { ... };
2

По вопросам рекламы [email protected]