В настоящее время я пишу свой первый большой c ++ — проект, но при запуске программы возникла ошибка сегментации. Я уже пытался отладить его с помощью valgrind, но пока безуспешно.
Поскольку программа довольно большая, я покажу только соответствующую функцию, в которой произошла ошибка:
void RigidBody::RotateAroundAxis( dReal Angle,
dRealVector3 Axis,
dRealVector3 Anchor)
{
std::cout<<"RotateAroundAxis BodyID: " << this->GetBodyId()<<std::endl;
dRealMatrix3 RotationMatrix=HelperFunctions::RotateAroundAxis(Angle, Axis);
dRealMatrix3 CurrentRotation=this->GetRotation();
dRealVector3 Position=this->GetPosition();
dRealMatrix3 newRotationMatrix=boost::numeric::ublas::prod(RotationMatrix,CurrentRotation);
std::cout<<"RotateAroundAxis (Debug0) BodyID: " << this->GetBodyId()<<std::endl;
SetRotation(newRotationMatrix);
std::cout<<"RotateAroundAxis Debug"<<std::endl;// This is the last line that is processed without an error.
std::cout<<"RotateAroundAxis (Debug1) BodyID: " << this->GetBodyId()<<std::endl; // This line probably causes the error.
// object is now rotated but needs to be translated
boost::numeric::ublas::bounded_vector<dReal,3> PosRelToAnchor;
std::cout<<"RotateAroundAxis (Debug2) BodyID: " << this->GetBodyId()<<std::endl;
for(unsigned int i=0;i<3;i++){PosRelToAnchor[i]=Position[i]-Anchor[i];};
PosRelToAnchor=boost::numeric::ublas::prod(RotationMatrix,PosRelToAnchor);
for(unsigned int i=0;i<3;i++){Position[i]=PosRelToAnchor(i)+Anchor[i];};
SetPosition(Position);
}
Я поместил некоторые сообщения в функцию, чтобы отследить, где происходит ошибка. Выход в терминал:
SetRotation BodyID: 0x854de60
SetPosition0
SetPositionBodyID0x854de60
SetPosition1
SetPositionEnd
SetRotation (Debug1) BodyID: 0x854de60
SetRotationEnd
RotateAroundAxis Debug
*** Program received signal SIGSEGV (Segmentation fault) ***
Вызов функции ‘this-> GetBodyId ()’ выполняется раньше без каких-либо проблем, а затем внезапно вызывает ошибку, и я понятия не имею, почему это происходит.
Используя valgrind, я получил следующий вывод:
==10910== Invalid read of size 8
==10910== at 0x409AF5: RigidBody::RotateAroundAxis(double, boost::array<double, 3ul>, boost::array<double, 3ul>) (RigidBody.cpp:353)
==10910== by 0x40FFF7: Joints::Hinge::Hinge(dxWorld*, std::string, boost::array<double, 3ul>, boost::array<double, 3ul>, boost::shared_ptr<RigidBody>, boost::shared_ptr<RigidBody>, double) (Joints.cpp:55)
==10910== by 0x410563: BioFlexRotatory::BioFlexRotatory(dxWorld*, unsigned char, boost::array<double, 3ul>, boost::array<double, 3ul>, boost::shared_ptr<RigidBody>, boost::shared_ptr<RigidBody>, double, double, double) (BioFlexRotatory.cpp:30)
==10910== by 0x40BE9B: Universe::AddBioFlexRotatory(unsigned char, boost::array<double, 3ul>, boost::array<double, 3ul>, boost::shared_ptr<RigidBody>, boost::shared_ptr<RigidBody>, double, double, double) (Universe.cpp:186)
==10910== by 0x406CFE: main (main.cpp:75)
==10910== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==10910==
==10910==
==10910== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==10910== Access not within mapped region at address 0x0
==10910== at 0x409AF5: RigidBody::RotateAroundAxis(double, boost::array<double, 3ul>, boost::array<double, 3ul>) (RigidBody.cpp:353)
==10910== by 0x40FFF7: Joints::Hinge::Hinge(dxWorld*, std::string, boost::array<double, 3ul>, boost::array<double, 3ul>, boost::shared_ptr<RigidBody>, boost::shared_ptr<RigidBody>, double) (Joints.cpp:55)
==10910== by 0x410563: BioFlexRotatory::BioFlexRotatory(dxWorld*, unsigned char, boost::array<double, 3ul>, boost::array<double, 3ul>, boost::shared_ptr<RigidBody>, boost::shared_ptr<RigidBody>, double, double, double) (BioFlexRotatory.cpp:30)
==10910== by 0x40BE9B: Universe::AddBioFlexRotatory(unsigned char, boost::array<double, 3ul>, boost::array<double, 3ul>, boost::shared_ptr<RigidBody>, boost::shared_ptr<RigidBody>, double, double, double) (Universe.cpp:186)
==10910== by 0x406CFE: main (main.cpp:75)
==10910== If you believe this happened as a result of a stack
==10910== overflow in your program's main thread (unlikely but
==10910== possible), you can try to increase the size of the
==10910== main thread stack using the --main-stacksize= flag.
==10910== The main thread stack size used in this run was 8388608.
==10910==
==10910== FILE DESCRIPTORS: 3 open at exit.
==10910== Open file descriptor 2: /dev/pts/6
==10910== <inherited from parent>
==10910==
==10910== Open file descriptor 1: /dev/pts/6
==10910== <inherited from parent>
==10910==
==10910== Open file descriptor 0: /dev/pts/6
==10910== <inherited from parent>
==10910==
==10910==
==10910== HEAP SUMMARY:
==10910== in use at exit: 5,521 bytes in 36 blocks
==10910== total heap usage: 39 allocs, 3 frees, 5,803 bytes allocated
==10910==
==10910== 24 bytes in 1 blocks are still reachable in loss record 1 of 36
==10910== at 0x4C286E7: operator new(unsigned long) (vg_replace_malloc.c:287)
==10910== by 0x40C990: Universe::AddRigidBody(std::string, dMass, boost::array<double, 3ul>, boost::numeric::ublas::c_matrix<double, 3ul, 3ul>, boost::array<double, 3ul>, std::string) (shared_count.hpp:91)
==10910== by 0x4068AE: main (main.cpp:52)
==10910==
==10910== 24 bytes in 1 blocks are still reachable in loss record 2 of 36
==10910== at 0x4C286E7: operator new(unsigned long) (vg_replace_malloc.c:287)
==10910== by 0x40C990: Universe::AddRigidBody(std::string, dMass, boost::array<double, 3ul>, boost::numeric::ublas::c_matrix<double, 3ul, 3ul>, boost::array<double, 3ul>, std::string) (shared_count.hpp:91)
==10910== by 0x406A0E: main (main.cpp:56)
==10910==
(Это продолжается довольно долго. Если это поможет, я могу опубликовать полный вывод.)
Однако это мне совсем не помогает, потому что я понятия не имею, что он пытается мне сказать. Поиск «Valgrind Invalid read of size» также не дал мне никаких подсказок о том, с чего начать.
Итак, есть идеи, как исправить эту ошибку?
ОБНОВИТЬ:
До этой записи я пытался отладить ошибку, используя gdb. Поскольку я впервые столкнулся с такой ошибкой, я предпочел версию с графическим интерфейсом (KDevelop 4). Я установил точку останова, а затем прошел через линии. Однако, согласно отладчику, адрес, на который указывал указатель this, был постоянным (и правильным) все время. Все выглядело хорошо до линии, где программа потерпела крах. И отчет о сбое не сказал мне ничего ценного (в зависимости от того, какую функцию я вызывал через this-указатель, он показал мне, что источником ошибки является одна из библиотек std, такая как «libstdc ++. So.6», что я считал маловероятным.) Затем я попробовал valgrind, отладчик, который специализируется на таких ошибках доступа к памяти (согласно другим записям на форуме).
Прочитав ответы, я дал еще один шанс отладки и вставил строку ‘std :: cout<<«Этот указатель указывает на» << этот << std :: endl; ‘ в разных местах. И, как оказалось, указатель действительно указывает на нуль после вызова функции SetRotation. Внутри этой функции я записал в [12] элемент массива, который имеет двенадцать элементов (но начинается с нуля, поэтому заканчивается в элементе [11]). Классическая ошибка для тех, кто работает с Matlab большую часть времени. Я исправил это, и программа работает без ошибок. Затем я снова обнаружил ошибку и снова посмотрел, используя gdb. Но это все еще говорит, что этот указатель указывает на правильное место. Я не знаю, в чем проблема с отладчиком. Не обновляется ли он или что-то еще, но он не дает мне никаких намеков на то, что я сделал неправильно.
Так что либо в gdb, либо в графическом интерфейсе KDevelop для gdb есть ошибка, скрывающая мою собственную ошибку.
Большое спасибо за помощь в исправлении ошибки.
Неверное чтение размера 8
означает, что программа пыталась прочитать 8 байтов из недопустимой ячейки памяти.
Адрес 0x0 не является стековым, malloc’d или (недавно) свободным
означает, что адрес был нулевым — поэтому вы пытаетесь прочитать нулевой указатель.
в 0x409AF5: RigidBody :: RotateAroundAxis (double, boost :: array, boost :: array) (RigidBody.cpp: 353)
означает, что код, который пытался это сделать, был в строке 353 RigidBody.cpp
в функции под названием RotateAroundAxis
, Я предлагаю вам взглянуть на эту строку; если нет очевидной проблемы, то, возможно, вы могли бы отметить ее в своем примере кода, чтобы мы могли взглянуть. Возможно, стоит запустить код в отладчике; он должен остановиться на ошибке сегментации и позволить вам проверить соответствующие переменные.
Мне кажется, ты звонишь RigidBody
функционировать через RigidBody*
это установлено 0
,
Кроме того, у вас есть ошибка в SetRotation
это портит вашу память до неузнаваемости.
Вам нужно использовать свой отладчик.