[C++] бага g++?
Так валится же после инициализации - есть уверенность, что &m и &n валидны?
int m, n;
Есть ощущение, что конструктор Tetrahedronizer вылазит за пределы своей памяти, но не понятно где.
Выложи код полностью, без троеточий.
конструктор не может завершиться позже первого оператора printf
int main(void)
{
Cell cell;
FILE *file, *res;
int m, n;
char buf[128];
double max_h, min_h;
double t1, t2, t3;
unsigned cc;
unsigned cn;
double *pts;
int FEM_n = 23;
double cres1 = 0.0, cres2 = 0.0;
double l1res1 = 0.0, l1res2 = 0.0;
file = fopen ("test.dat", "r");
if (file == 0)
{
printf ("cannot open 'test.dat'\n");
return 0;
}
Tetrahedronizer t(0);
printf ("1\n");
while (fscanf (file, "%d %d", &m, &n) == 2)
{
printf ("2\n");
max_h = 1.0 / (double)m;
min_h = 1.0 / (double)n;
...
}
}
cell.cpp
Cell::Cell (Cell *p)
{
leaf = true;
u[0] = u[1] = v[0] = v[1] = w[0] = w[1] = 0.0;
children[0] = children[1] = children[2] = children[3] = children[4] = children[5] = children[6] = children[7] = 0;
parent = p;
if (parent)
depth = parent->depth + 1;
else
depth = 0;
center[0] = 0.5;
center[1] = 0.5;
center[2] = 0.5;
side = 1.0;
ind = -1;
}
cell.h
class Cell
{
public:
Cell *children[8];
Cell *parent;
int depth;
int ind;
double u[2];
double v[2];
double w[2];
bool leaf;
int flags;
double center[3];
double side;
Cell (Cell *parent = 0);
...
};
да, и что?
Еще желательно printf заменить на fprintf(stderr,
int foo;
Tetrahedronizer t(0);
int bar;
printf ("1 %d %d %d\n", &foo, &bar, sizeof(t;
int foo;
Tetrahedronizer t(0);
int bar;
fprintf (stderr, "1 %p %p %d\n", &foo, &bar, sizeof(t;
while (fscanf (file, "%d %d", &m, &n) == 2)
{
fprintf (stderr, "2\n");
max_h = 1.0 / (double)m;
min_h = 1.0 / (double)n;
$ ./test
1 0x7ffff1976914 0x7ffff1976910 80
2
2
Segmentation fault
стало еще интереснее. Правда в цикле уже используется t, если отключить его использование, то все нормально. Вопрос, правда, все равно остался: в чем дело?
Под gdb запускал?
нет, не умею им дебажить...Да и вообще, редко приходится дебажить )
Поведение, где для падения требуется использование t в цикле — лишнее, его рассматривать не надо, и так какой-то глюк (скорее всего порча памяти).
std::map<cell_t, int> completed_sections;
что с этим делать и куда писать? Может ли быть такое, что с вектором или сэтом такая же музыка? разбираться в STL коде может быть себе дороже
Разбираться в STL-коде для поиска багов не надо Надо разбираться в своем коде и понять, почему ваш класс не подходит для использования в map. Давайте код cell поближе (конструкторы, деструкторы, операторы присваивания и сравнения на всякий ).
А, cell_t — указатель, тогда не надо
Собственно, тогда что делать? от STL отказываться не очень хочется, да и вроде он, говорят, хорошо отлажен...
не, не надо от него отказываться. Надо думать
Можно под valgrind'ом запустить, мб понимание придёт быстрее.
я плохо умею пользоваться отладчиками по той причине, что редко (с ходу не припомню) приходится отлаживать программы на таком уровне.
кстате, фишка в том, что бага может быть все еще не в этом конкретном мапе Да и скорее всего не в нем (там простыми типами инстанцируется).
Ну скинь, у меня 20 минут есть.
а насколько хорошо использовать в качестве ключей указатель? Просто меня это почему-то смущает
ну я глубоко не задумываюсь (потому что трудно сейчас но мной завладела мысль, что это то же самое, что и целое число в некотором смысле
есть бредовая идея, попробуй поменять std::map на std::tr1 ::unordered_map
error: ‘std::tr1’ has not been declared
#include <tr1/unordered_map>
gdb yourprogram
потом в ней r<Enter>
и когда вывалится (ахтунг - может и не вываливаться) жамкаеш bt<Enter>
потом смотришь стек
но ящетаю, это не оно, хотя может и починиться на некоторых тестах заменой
1
Segmentation fault
(убрал foo и bar, т.е. все так, как было изначально).
для gdb наверное ее надо как-нибудь по особому собрать?
CXXFLAGS=-g3
1
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff731eb2b in _IO_vfscanf from /lib/libc.so.6
(gdb) bt
0x00007ffff731eb2b in _IO_vfscanf from /lib/libc.so.6
0x00007ffff7325f78 in fscanf from /lib/libc.so.6
0x000000000040211a in main at test.cpp:96
(gdb)
ну и что с этим делать?
а, кстати, почему ты сделал вывод, что проблема в мапе? Когда его убираешь, все отрабатывает? Так это не значит. Вот если убираешь все, кроме него и не работает, то еще может быть. Я это к тому, что таки да, хуйни с STL надо убирать не делением попалам нифига, а перебрать там побольше вариантов.
Перепробовал кучу вариантов - работает только с не более чем тремя контейнерами oO
значит надо перед каждым сканфом следить, чтобы &m и &n не менялись
Очень странный адрес у либ с. Он со стеком не конфликтует случаем.
Слинкуй статически, это писец какой-то, как так вообще можно было туда библиотеку загрузить.
ну и gcc -v заодно
бага g++?бага в программе
$ apt-cache policy libc6
libc6:
Installed: 2.11.2-10
Candidate: 2.11.2-10
Version table:
*** 2.11.2-10 0
500 http://mirror.yandex.ru/debian/ squeeze/main amd64 Packages
100 /var/lib/dpkg/status
$ gcc -v
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.5-8' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.4 --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.4.5 (Debian 4.4.5-8)
Ошибка, очевидно, в код—компилятор, причем тут линковка?
Отмечу, после инициализации t переменная n меняет свое значение на 0.
Прога не работает если используются одновременно 4 контейнера. С первыми 3мя программа работала и работала верно, но потом в целях изучения данной ситуации пришлось закоментить кучу кода и, как посоветовали, пробовать разные комбинации STL-контейнеров. Поэтому я не могу сказать о правильной работе с любыми тремя, но сегфолтов не происходит.
как могут поменяться адреса переменных?ну у тебя же меняется адрес локальной переменной, когда происходит рекурсивный вызов функции. Это длинная история, если знаком с архитектурой, то в кратце так: локальные переменные отсчитываются от BP, если кто-то засрал стек, то после выхода из функции может из стека достаться левый BP, соответственно, локальные переменные будут иметь левые адреса.
$ ./test
1 0x7fff4b7034ac 0x7fff4b7034a8
1 0x7fff4b7034ac 0x7fff4b7034a8
1
Segmentation fault
вот конструкторы и операторы сравнения:
typedef unsigned point_index_t;
struct point_t
{
double p[3];
double f;
};
struct edge_t
{
point_index_t i[3];
edge_t { }
edge_t (point_index_t i0, point_index_t i1, point_index_t i2)
{
i[0] = i0;
i[1] = i1;
i[2] = i2;
}
};
struct tetrahedron_t
{
point_index_t i[4];
tetrahedron_t { }
tetrahedron_t (point_index_t i0, point_index_t i1, point_index_t i2, point_index_t i3)
{
i[0] = i0;
i[1] = i1;
i[2] = i2;
i[3] = i3;
}
};
struct face_t
{
cell_t cell;
point_index_t i[2];
face_t { }
face_t (cell_t c, point_index_t i0, point_index_t i1)
{
cell = c;
i[0] = i0;
i[1] = i1;
}
face_t (cell_t c)
{
cell = c;
}
bool operator == (const face_t &face) const
{
return cell == face.cell;
}
bool operator < (const face_t &face) const
{
return cell < face.cell;
}
};
Линковка может быть при том, что область libc (cat /proc/<PID>/maps во время выполнения) может быть расположена близко к стеку, при этом создание класса на стеке, а не на куче отжирает много памяти, сдвигая стек-пойнтер как раз к области libc, и, возможно, "заезжает" немного туда, захерачивая системные переменные.
Tetrahedronizer *t = new Tetrahedronizer(0);
delete t;
$ ./test
1 0x7fffa32abf7c 0x7fffa32abf78
*** glibc detected *** ./test: free: invalid next size (fast): 0x0000000001b7e250 ***
======= Backtrace: =========
/lib/libc.so.6(+0x71ad6)[0x7ffd92c4cad6]
/lib/libc.so.6(cfree+0x6c)[0x7ffd92c5184c]
./test[0x401943]
/lib/libc.so.6(__libc_start_main+0xfd)[0x7ffd92bf9c4d]
./test[0x401669]
======= Memory map: ========
00400000-004e7000 r-xp 00000000 08:15 131033 /programming//cell/test
006e7000-006e8000 rw-p 000e7000 08:15 131033 /programming//cell/test
01b7e000-01b9f000 rw-p 00000000 00:00 0 [heap]
7ffd8c000000-7ffd8c021000 rw-p 00000000 00:00 0
7ffd8c021000-7ffd90000000 ---p 00000000 00:00 0
7ffd92bdb000-7ffd92d33000 r-xp 00000000 08:05 97739 /lib/libc-2.11.2.so
7ffd92d33000-7ffd92f32000 ---p 00158000 08:05 97739 /lib/libc-2.11.2.so
7ffd92f32000-7ffd92f36000 r--p 00157000 08:05 97739 /lib/libc-2.11.2.so
7ffd92f36000-7ffd92f37000 rw-p 0015b000 08:05 97739 /lib/libc-2.11.2.so
7ffd92f37000-7ffd92f3c000 rw-p 00000000 00:00 0
7ffd92f3c000-7ffd92f52000 r-xp 00000000 08:05 97731 /lib/libgcc_s.so.1
7ffd92f52000-7ffd93151000 ---p 00016000 08:05 97731 /lib/libgcc_s.so.1
7ffd93151000-7ffd93152000 rw-p 00015000 08:05 97731 /lib/libgcc_s.so.1
7ffd93152000-7ffd931d2000 r-xp 00000000 08:05 97748 /lib/libm-2.11.2.so
7ffd931d2000-7ffd933d2000 ---p 00080000 08:05 97748 /lib/libm-2.11.2.so
7ffd933d2000-7ffd933d3000 r--p 00080000 08:05 97748 /lib/libm-2.11.2.so
7ffd933d3000-7ffd933d4000 rw-p 00081000 08:05 97748 /lib/libm-2.11.2.so
7ffd933d4000-7ffd934ca000 r-xp 00000000 08:07 1294364 /usr/lib/libstdc++.so.6.0.13
7ffd934ca000-7ffd936ca000 ---p 000f6000 08:07 1294364 /usr/lib/libstdc++.so.6.0.13
7ffd936ca000-7ffd936d1000 r--p 000f6000 08:07 1294364 /usr/lib/libstdc++.so.6.0.13
7ffd936d1000-7ffd936d3000 rw-p 000fd000 08:07 1294364 /usr/lib/libstdc++.so.6.0.13
7ffd936d3000-7ffd936e8000 rw-p 00000000 00:00 0
7ffd936e8000-7ffd93706000 r-xp 00000000 08:05 97751 /lib/ld-2.11.2.so
7ffd938e9000-7ffd938ed000 rw-p 00000000 00:00 0
7ffd93903000-7ffd93905000 rw-p 00000000 00:00 0
7ffd93905000-7ffd93906000 r--p 0001d000 08:05 97751 /lib/ld-2.11.2.so
7ffd93906000-7ffd93907000 rw-p 0001e000 08:05 97751 /lib/ld-2.11.2.so
7ffd93907000-7ffd93908000 rw-p 00000000 00:00 0
7fffa3299000-7fffa32ae000 rw-p 00000000 00:00 0 [stack]
7fffa3345000-7fffa3346000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
кстати, это уже интереснее
через валгринд надо пропускать
ну так чо воспроизводится у кого нибудь?..
я ему еще не кидал; тебе тоже могу кинуть. Если хочешь в этом покопаться, то куда кидать?
Сделай _простой_ пример. Чтобы не было "а вот тут у меня еще кусочек кода есть, но он точно не может ни на что влиять, наверное". Минимизируй его. Если лень руками, возьми delta (delta.tigris.org). После этого станет очевидно где у тебя ошибка.
А еще лучше - запусти под валгриндом.
valgrind ./testвыдает дофига всего, но все в таком виде:
==2183== Invalid write of size 8
==2183== at 0x40349D: std::_Rb_tree<Cell*, std::pair<Cell* const, int>, std::_Select1st<std::pair<Cell* const, int> >, std::less<Cell*>, std::allocator<std::pair<Cell* const, int> > >::_Rb_tree_impl<std::less<Cell*>, false>::_Rb_tree_impl (stl_tree.h:434)
==2183== by 0x4030F3: std::_Rb_tree<Cell*, std::pair<Cell* const, int>, std::_Select1st<std::pair<Cell* const, int> >, std::less<Cell*>, std::allocator<std::pair<Cell* const, int> > >::_Rb_tree (stl_tree.h:591)
==2183== by 0x402E9B: std::map<Cell*, int, std::less<Cell*>, std::allocator<std::pair<Cell* const, int> > >::map (stl_map.h:151)
==2183== by 0x402BBF: Tetrahedronizer::Tetrahedronizer(int) (tetrahedronizer.cpp:33)
==2183== by 0x40190A: main (test.cpp:92)
==2183== Address 0x5936318 is 8 bytes after a block of size 80 alloc'd
==2183== at 0x4C24DFA: operator new(unsigned long) (vg_replace_malloc.c:261)
==2183== by 0x4018F7: main (test.cpp:92)
еще примерно столько же сообщений Invalid read of size 8
ну и вот в конце:
1 0x7ff00012c 0x7ff000128 8
1
2
valgrind: m_mallocfree.c:225 (mk_plain_bszB): Assertion 'bszB != 0' failed.
valgrind: This is probably caused by your program erroneously writing past the
end of a heap block and corrupting heap metadata. If you fix any
invalid writes reported by Memcheck, this assertion failure will
probably go away. Please try that before reporting this as a bug.
нужен ли весь список?
и что с этим делать?
выложил бы архив с исходниками на форум - давно б тебе уже все решили наверняка
у меня есть 2 файла: tetra.h и tetra.hpp. Реализацию класса я делаю согласно объявлению в .hpp (т.е. в tetrahedronizer.cpp стоит #include "tetra.hpp" а вызываю согласно .h (т.е. в main.cpp стоит #include "tetra.h"). Забавно то, что линкер не ругался на это, хотя это вполне логично — класc, описанный в .h, определен. Интересная ситуация и хороший опыт
Вердикт — бага моя ) было бы совсем печально, если бы было не так
Помог совет "минимизации кода", когда я удалил tetra.h (т.к. он мне на самом деле не нужен прога не собиралась.
Всем спасибо.
Это C++
hppдовыделывался с модным расширением, ящетаю
2) emacs и geany лучше (с точки зрения синтаксиса) подсвечивают такие файлы по умолчанию. Конечно, можно настроить и для .h, но зачем?
PS Я, кстати, не использую protected и наследование в черт пойми каких местах (это насчет выделываюсь)
А расширения для компилируемых файлов помогают тому же gcc всего-навсего определиться с языком. Нормальные редакторы-вьюверы и h-файлы "из коробки" подсвечивают сразу правильно.
и как редактору C и C++ различать?
И причем тут "коробка"?
и как редактору C и C++ различать?щетать, что C++ по умолчанию. Что из-за этого может неправильно подсветиться? Я еще понимаю, можно придумать код, который не откомпилится плюсами, но подсветке точно пох.
ну вот typedef A B в geany подсвечивается по разному относительно языка. В .hpp еще выделится B, например. То же самое относительно структур и классов.
подсветит class или public не как переменную, а как ключевое слово. в особо хитрых редакторах ещё и скажет что ошибка у тебя и выделит красным.
если явно писать gcc main.cpp, разве будет выбор языка внутри gcc? Это если, например, cmake делать, то тогда он взависимости от расширения будет делать gcc или g++
компилировать будет ок, скомпоновать не получится.
Ладно, поторопился
1) это не модное, а правильное расширение. Чувствуешь разницу? Может ты C++ код в .c файлах пишешь, но я использую .cpp. Если говорить о модности, то это скорее .cxx и .hxxправильное относительно чего? c - язык Си, c++ - язык Си Плюс Плюс; h - header. Если не ошибаюсь, насчет расширений ни в каком стандарте ничего не сказано.
2) emacs и geany лучше (с точки зрения синтаксиса) подсвечивают такие файлы по умолчанию. Конечно, можно настроить и для .h, но зачем?Подсветка синтаксиса не должна от расширения зависить. Нужно определиться на каком языке ты пишешь и соответствующим образом настроить среду. Смешивать языки, тем более такие похожие как C и C++ - это зло.
PS Я, кстати, не использую protected и наследование в черт пойми каких местах (это насчет выделываюсь)
Этого вообще не понял. Наследование и защищенные члены и методы это просто инструмент, которым надо пользоваться, если ты используешь ООП. Гордиться тем, что ты их не используешь - глупо. Как вообще можно использовать ООП без наследования?
Подсветка синтаксиса не должна от расширения зависить. Нужно определиться на каком языке ты пишешь и соответствующим образом настроить среду. Смешивать языки, тем более такие похожие как C и C++ - это зло.и держать две среды, если в одних проектах C, а в других C++?
защищенные члены и методыа разве сам Страуструп не признал, что protected нахрен не нужно?
нет, не держать 2 среды. Настройки используемого языка должны быть в файле проекта среды. Или среда cannot into per project settings?
не знаю. давай цитату - номер тома полного собрания сочинений, глава, etc
нет, не держать 2 среды. Настройки используемого языка должны быть в файле проекта среды. Или среда cannot into per project settings?а если брать вариант, когда над одними и теми же проектами работают разные люди в разных редакторах?
тогда проще договориться о разных расширениях, чем о единых project settings
для C++ .cpp .hpp, .cxx .hxx
это трудно? это и есть стандарт. Хедеры в си++ отличаются от хедеров в си. Ок, не стандарт, а рекомендация.
Подсветка синтаксиса не должна от расширения зависить. Нужно определиться на каком языке ты пишешь и соответствующим образом настроить среду. Смешивать языки, тем более такие похожие как C и C++ - это зло.Исторически так сложилось, что, к сожалению для тебя, .c и .h — это файлы Си. И подсвечиваться они должны согласно синтаксису Си.
Этого вообще не понял. Наследование и защищенные члены и методы это просто инструмент, которым надо пользоваться, если ты используешь ООП. Гордиться тем, что ты их не используешь - глупо. Как вообще можно использовать ООП без наследования?часто делаешь приватные конструкторы? имхо это реально единственное место, где критично нужен private в твоей программе. В protected за 10 лет программирования я пока большого смысла не увидел, увы. Это, конечно, не касается тех случаев, когда ты пишешь какую-нибудь библиотеку аля того же STL, которой будут пользоваться. В чем я дико сомневаюсь.
Помимо полиморфизма (а зачем по сути нужно еще наследование? напомню, есть еще пара концепций ООП. Почитать можно в Б. Страуструп, например.
btw, все сторонние пакеты (хотя их не так много которые мне приходилось собирать, используют именно грамотные расширения. В основном это .hxx и .cxx для С++ и .c, .h для С.
неа, если в одном проекте не перемешаны файлы из C и C++, то пусть каждый в своей среде определит - что он открывает в данный момент. Если перемешаны - то да, имеет смысл разделять по расширениям, но уже сама эта ситуация это не совсем хорошо.
это и есть стандарт.RFC please.
признавал, помню. И нигде в его примерах толком не было protected (кроме главы о самом protected).
часто делаешь приватные конструкторы? имхо это реально единственное место, где критично нужен private в твоей программе. В protected за 10 лет программирования я пока большого смысла не увидел, увыno comments
кстати, совсем забыл, еще весьма популярные .cc и .hh.
неа, если в одном проекте не перемешаны файлы из C и C++, то пусть каждый в своей среде определит - что он открывает в данный момент. Если перемешаны - то да, имеет смысл разделять по расширениям, но уже сама эта ситуация это не совсем хорошо.В проектах, которыми я занимаюсь по учебе, замешаны не только Си и Си++, а еще фортран и питон, например. Такая ситуация наверное вообще катастрофическая, да? Хотя, теоретически, все можно в .c писать и не париться. Компилятор(ы) все поймет(ут) Большинство людей в моей команде (внимание!) пишут на Си++ в стиле Си. Без protected'ов. Как в индии короче
И еще, языки Си и Си++ отнюдь не похожи. Схожи синтаксисы, не более.
В проектах, которыми я занимаюсь по учебе, замешаны не только Си и Си++, а еще фортран и питон, например.мое сочувствие.
И еще, языки Си и Си++ отнюдь не похожи. Схожи синтаксисы, не более.
кэп, я про схожесть синтаксиса и говорил.
мое сочувствие.в твоих локальных поделках (впрочем, как и в моих можно обойтись и без фортрана — понятно. Но если пишешь что-нибудь более менее разумное и математическое, то без фортрана и прекрасно отлаженных пакетов на нем не обойтись. Видимо, ты мало участвовал (если вообще участвовал) в подобных проектах.
кэп, я про схожесть синтаксиса и говорил.молодец!
"более менее разумное" далеко не всегда равно "математическое"
мои "локальные поделки" востребованы на рынке.ну примерчик кинь, чтоли.
"более менее разумное" далеко не всегда равно "математическое"я поэтому и поставил "и".
не думаю что примерчик будет широко известен, все-таки это не десктопный рынок. конкретнее - эмуляция SNMP-устройств, транслятор all2snmp.
Че спорите? С++ по любому говно, прогать надо на джаве.
толсто, бро.
Богачева на тебя нет
// vim: set noai ts=2 sw=4 syntax=on tw=78 filetype=c: а остальные пусть
// ебуццо в гамаке в лыжах
Смешивать языки, тем более такие похожие как C и C++ - это зло.иногда это необходимо
Пианиста на тебя нет
Я вот тоже не пойму смысла твоего появления в теме, когда проблема была решена и тема уже, в общем-то, была закрыта. Может ты мне дельные советы дать хотел? Или что?я так просто флуднуть зашёл. не думал что ты так близко к сердцу воспримешь.
Оставить комментарий
Sachaa
main.cpptetra.hpp
tetrahedronizer.cpp
собирал без оптимизаций и прочего:
CXXFLAGS =
вот test.dat:
запускаем:
$ ./test
1
Segmentation fault
если убрать Tetrahedronizer t(0) из кода, то все работает.
Что это может быть? На lenny этот код работал и работал правильно. На squeeze, как видно, что-то не так...