C ++ Копировать через задачу присваивания - PullRequest
0 голосов
/ 22 июля 2010

Кажется, у меня возникли проблемы со следующей функцией:

void OtherClass::copy_this( int index, MyClass &class_obj)
{
    if(index < MAX_index)
        class_obj = array_of_MyClass[index];
}

OtherClass поддерживает массив объектов MyClass, и я хотел бы, чтобы эта функция копировала выбранный объект из массива в предоставленный class_obj.

При запуске программа имеет ошибку сегментации, когда достигает этой функции.Запуск его в gdb и просмотр обратной трассировки показывает, что когда он попадает в строку назначения, выполнение переходит назад почти на 100 строк в середину совершенно другой функции.Строка, к которой он переходит, выглядит следующим образом:

temp_obj = array_of_MyClass[other_index]

И соответствующий вывод обратной трассировки GDB:

#0  0x0000003c7ae7256c in memcpy () from /lib64/tls/libc.so.6
#1  0x000000000043264e in MyClass::operator= (this=0x4c0000004c, _ctor_arg=@0x7fbffd8228) at ../location.cpp:156
#2  0x0000000000432569 in OtherClass::copy_this (this=0x7fbffd8220, index=0, section=@0x4c0000004c) at ../location.cpp:254

Очевидно, что это тот же тип операции, но почему выполнение будет перенесенокак это?У меня нет длинных прыжков, gotos и т. Д. Где-либо в программе.У меня также нет пользовательских операторов присваивания, конструкторов копирования и т. Д., Поэтому «operator =» из обратной трассировки вызывает недоумение.

Прежде чем кто-либо спросит, нет, я не могу опубликовать весь код.(Извините!) Я понимаю, что это может сделать невозможным определить мою проблему;если это так, просто дайте мне знать.

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


После повторного прохождения и тестирования пары «простейших» случаев, кажется, что проблема фактически возникла где-то на более раннем этапе выполнения, поэтому я вернулся к чертежной доске для меня.Спасибо всем за помощь!

Ответы [ 5 ]

0 голосов
/ 23 июля 2010

Стоило бы обратить внимание еще на несколько кадров назад, и я бы увидел ответ.

Объект MyClass, в который я пытался скопировать данные, был инициализирован как указатель NULL, откуда и произошла ошибка в memcpy(). («Невозможно получить доступ к памяти по адресу 0x0» - черт!) Не могу поверить, что я пропустил это ...

Спасибо за вашу помощь - я, вероятно, продолжил бы бить себя головой о стену, если бы я не опробовал ваши решения. Явное написание оператора присваивания убедило меня, что проблема была в другом месте.

Gratia plena!

0 голосов
/ 22 июля 2010

У вас их нет, но компилятор их все равно выдает, что вы и назвали, когда использовали на нем оператор =.Скорее всего, для MyClass недостаточно оператора присваивания по умолчанию, поэтому он не работает.Реализуйте их в явном виде и посмотрите, решит ли это проблему.

Без дополнительного исходного кода можно рекомендовать немного больше.

0 голосов
/ 22 июля 2010

Код скомпилирован с флагами оптимизатора? Оптимизатор может делать очень странные вещи с потоком выполнения, в том числе переходить от одной функции к совершенно не связанной функции, у которой просто есть фрагмент кода, выполняющий то, что нужно первой функции.

0 голосов
/ 22 июля 2010

строка, с которой вы говорите, что выполнение переходит назад, является присваиванием объекту класса MyClass. Вот почему вы видите MyClass::operator= в вашем следе. Вы говорите, что у вас нет пользовательских операторов присваивания или конструкторов копирования, так что это объяснило бы memcpy () прямо над ним в обратном следе, так как это реализация по умолчанию для копирования (мелкая копия.)

В этом случае я думаю, что было бы полезно реализовать конструктор копирования (для Myclass).

Что касается самого segfault - как был инициализирован массив? что было в индексе 0 массива? (который, кажется, использовался в вызове)

0 голосов
/ 22 июля 2010

Является ли индекс действительным?Я вижу, что вы сравниваете с MAX_index, но содержит ли ваш массив MAX_index, инициализированные элементы?Я спрашиваю, потому что, если вы копируете недопустимый объект, у вас есть неопределенное (неприятное) поведение, как вы описали.

Другая возможность (если не эта) состоит в том, что пришло время полностью восстановить.Либо отладочная информация повреждена, либо сгенерированный код неполон (по тем или иным причинам в процессе сборки).

...