У меня есть проблема с моим кодом, которая имеет некоторые очень странные симптомы.
Код скомпилирован на моем компьютере со следующими версиями:
а. Версия GCC: 4.4.2
б. CMAKE verson: 2.8.7
с. QNX (операционная система) версия: 6.5.0
И в коде есть ошибка, в то время как освобождается некоторая память и происходит выход из функции (не умирая ни при каком коде, просто при выходе из функции).
Странные вещи об этом:
Код делает это в режиме выпуска, но не в режиме отладки:
а. Код является многопоточным, так что это указывает на состояние гонки.
б. Я не могу отладить, переведя его в режим отладки.
Код, скомпилированный на компьютере коллеги с одинаковыми версиями всего, не имеет этой проблемы.
а. Самое странное в этом то, что код рабочих партнеров работает, но также и то, что двоичный файл, созданный в результате компиляции на его машине, то есть примерно на 6 МБ больше.
Теперь, к сожалению, я не могу опубликовать код, потому что он слишком большой, а также для работы. Но может ли кто-нибудь указать мне путь к исправлению этого.
Поскольку я использую QNX, я ограничен в своих средствах отладки, я не могу использовать Valgrind, и, поскольку он не поддерживается в QNX, GDB на самом деле не помогает.
Я ищу любого, у кого была подобная / та же самая проблема и какова была причина и как они исправили это.
РЕДАКТИРОВАТЬ:
Оооо … Я узнал, что это было, но я все еще немного озадачен тем, как это произошло.
Код виновника был такой:
Eigen::VectorXd msBb = data.modelSearcher->getMinimumBoundingBox();
где определение для getMinimumBoundingBox
это:
Eigen::VectorXd ModelSearcher::getMinimumBoundingBox();
и он возвращает VectorXd, который всегда инициализируется как VectorXd output(6, 1)
, Так что я сразу подумал, правильно, это должно быть потому, что VectorXd не инициализируется, а изменяет его следующим образом:
Eigen::VectorXd msBb(6, 1); msBb = data.modelSearcher->getMinimumBoundingBox();
Но это не сработало. На самом деле мне пришлось исправить это, изменив определение функции следующим образом:
void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input);
и призыв к этому
Eigen::VectorXd msBb(6, 1); data.modelSearcher->getMinimumBoundingBox(msBb);
Итак, теперь новый вопрос:
Что за черт? Почему первая смена не сработала, а вторая сработала, почему я должен пройти по ссылке? О, и большой вопрос, как, черт возьми, это не сломалось, когда мой коллега скомпилировал его, и я запустил его? Это прямая ошибка памяти, конечно, это не должно зависеть от того, какой компьютер его компилирует, тем более что компилятор и все другие важные вещи одинаковы !! ??
Спасибо за помощь ребята.
… двоичный файл, созданный в результате компиляции на его компьютере, который составляет примерно 6 МБ больше
Стоит выяснить, в чем разница (даже если это только тот случай, когда его сборка скрывает, а ваша разоблачает настоящую ошибку):
-E
переключитесь на ваши аргументы gcc в cmake, чтобы он предварительно обрабатывал ваши файлы с тем же путем включения, что и при обычной компиляции; diff выход препроцессораnm
или же objdump
или что вам нужно для двух связанных исполняемых файлов: если какая-то системная или сторонняя библиотека представляет собой другую версию на одном компьютере, она может отображаться здесьldd
если он динамически связан, убедитесь, что они оба получают одинаковые версии библиотеки
pldd
, сравните .so
записи в /proc/pid/map
, запустите процесс под strace
/dtrace
/truss
и сравните активность компоновщика во время выполненияЧто касается кода … если это не работает:
Eigen::VectorXd ModelSearcher::getMinimumBoundingBox();
// ...
Eigen::VectorXd msBb(6, 1); msBb = data.modelSearcher->getMinimumBoundingBox();
и это делает:
void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input);
// ...
Eigen::VectorXd msBb(6, 1); data.modelSearcher->getMinimumBoundingBox(msBb);
у вас предположительно есть проблема с оператором присваивания. Если он выполняет поверхностное копирование и в векторе имеется динамически выделяемая память, у вас получится два вектора с одинаковым указателем, и они оба free
/delete
Это.
Обратите внимание, что если оператор вообще не определен, по умолчанию это мелкая копия.
Вы сказали, что должны измениться с:
void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input);
Что это было раньше?
Если бы это было:
void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd input);
и конструкторы копирования / операторы присваивания не были реализованы должным образом, это могло вызвать проблему.
Пожалуйста, проверьте, как они оба реализованы. Вот немного информации это может помочь.