2013-05-19 4 views
1

У меня есть небольшая ошибка, которая дует мне в голову. Возможно, это просто, но я полностью потерян.Значение возврата не такое же, как фактически возвращаемое значение?

У меня есть основной POD struct:

struct Data{ 
    bool isInvalid=false; 
    vec3 *vector; //vec3 is another struct with x,y,z components 
    Node*node; 
    bool isFresh; 
    unsigned int *form; 
    }; 

У меня есть функция:

Data getData(){ 
    Data forReturn; 
    //...populates the forReturn struct 
    cout<<forReturn.vector->x; //logs correctly a value 
    return forReturn; 
    } 

Журнал cout правильно показывает, что мое возвращение Data была заселена. Но когда я называю эту функцию из другой функции, возникает другая история:

Data newData=getData(); //logs as above 
    cout<<newData.vector->x; //is empty!! 

Что здесь происходит ?! Мой журнал выводит эти две строки рядом друг с другом, поскольку они происходят сразу после другого, но что происходит? Это не многопоточность, поэтому переменные и указатели не должны меняться между этими двумя строками!

+0

Можете ли вы показать все определение «данных»? –

+0

Что делает 'forReturn.vector' пункт to? BTW 'forReturn' не является указателем, поэтому' forReturn-> vector' не будет компилироваться. – juanchopanza

+0

sscce please ..... – Pubby

ответ

2

Я не могу точно сказать, если не вижу реального кода, который у вас есть, но моя ставка что ваша программа имеет неопределенное поведение, потому что вы разыскиваете висячий указатель. Я считаю, что в вашей getData() функции вы позволяете forReturn.vector точку локального объекта с автоматической продолжительности хранения, который разрушается при возвращении из getData(), например, так:

Data getData(){ 
    Data forReturn; 
    vec3 myVector; 
    // ... 
    forReturn.vector = &myVector; 
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
    // ... 
    cout<<forReturn.vector->x; // logs correctly a value 
    return forReturn; 
} 

В приведенном выше примере я возвращаюсь в Data объект forReturn по значению, то есть будет объявлен неявно объявленный конструктор перемещения (в C++ 11) или конструктор копирования (в C++ 03).

Поскольку эти неявно сгенерированные специальные функции-члены выполнить почленно движение или копию элементов структуры обработки данных, то vectorуказатель копируется, а это означает, что я возвращаю является объектом типа Data которого vector указатель указывает на объект, который уже вышел из сферы действия.

Это бомба замедленного действия. Как только этот указатель будет разыменован, «Boom». Обратите внимание, что «Boom» действительно может быть очень тихим взрывом. Неопределенное поведение означает, что ничего, кроме, может случиться, в том числе ничего.

+0

Как вспоминает Скотт Мейерс, _undefined behavior_ также может означать, что ваш жесткий диск можно стереть. :) – johnbakers

+0

@Fellowshee: [справа] (http://stackoverflow.com/questions/16428234/why-does-this-not-produce-a-segmentation-fault/16428253#16428253);) –

4

Если это так написано, локальные данные (forReturn) копируются во время процесса возврата. Поэтому важно, чтобы ваш экземпляр-конструктор класса Data реализован правильно (скопирует всех членов правильно)

+1

Также важно, что '... // заполняет forReturn struct', не связывает указатель' vector' с локальным объектом 'vec3' ... –

Смежные вопросы