2013-02-28 6 views
0

Я работаю над домашней работой, и у меня возникла странная проблема. Я надеюсь, что кто-то сможет мне помочь. У меня есть функция в середине моего кода:Почему адрес указателя меняется при возврате?

Token scheme::addScheme(vector <Token> toAdd) 
{ 

//Check if scheme is valid 
Token answer = isSchemeValid(toAdd); 
if (answer.retType() != "ok") 
{ 
    return answer; 
} 

identifierList * arrow = new identifierList(&(toAdd.at(0)), NULL); 
idList = arrow; 

for (int i = 2; i < toAdd.size()-1; i++) 
{ 
    (*arrow).id = &(toAdd.at(i)); 
    (*arrow).next= new identifierList(&(toAdd.at(0)), NULL); 
    arrow = (*arrow).next; 
} 


*id = toAdd.at(0); 
openParen = '('; 
closeParen = ')'; 

return Token("ok", "ok", 0); 
} 

Этот код делает все, что нужно это делать, за исключением самого конца. Он правильно устанавливает все переменные в то, что мне нужно. Вот где это не работает: я запускаю его шаг за шагом, и я вижу, что сразу после запуска последней строки return Token («ok», «ok», 0); значения idList изменяются от законных значений до сумасшедших (например, первый идентификатор в номере строки idList изменяется от 2 до -17891602.

это может иметь смысл, если я разместим заголовок для чего идентификаторList и Знак состоит из: Токена: #pragma раз используя патезрас; #include #include #include #include #include "datalogProgram.h"

enum state {COMMA, PERIOD, Q_MARK, LEFT_PAREN, RIGHT_PAREN, COLON, COLON_DASH, MULTIPLY, ADD, SCHEMES, FACTS, RULES, QUERIES, ID, STRING, COMMENT, WHITESPACE, UNDEFINED, ENDOFFILE, START}; 

class Token 
{ 
friend class datalogProgram; 

public: 
int lineNumber; 
string type; 
string value; 

Token(string inType, string inValue, int inLineNum); 
void route(state inState, string inValue, int inLineNum); 
string retType(); 
string retValue(); 

//A list of a bunch of functions that don't matter here. 
}; 

И identifie rList:

class identifierList 
{ 
friend class scheme; 
public: 
Token * id; 
identifierList * next; 

identifierList(Token * inId, identifierList * inNext); 
}; 

Я не понимаю, почему переменные меняются, когда все, что я делаю, возвращается из функции?

+3

Для удобства чтения предпочитайте 'arrow-> id' over' (* стрелка) .id'. – 2013-02-28 21:11:58

+0

Вы передаете вектор 'toAdd' по значению, чтобы получить копию вектора и его содержимого. Затем вы берете адрес векторных элементов: '& (toAdd.at (i))'. Когда вы покидаете функцию, копия вектора уничтожается, а указатели больше не действительны. Измените подпись 'addScheme', чтобы принять вектор по ссылке –

ответ

0

Это происходит потому, что вектор toAdd передается по значению, а не по ссылке. Случается, что вектор, который вы передаете в функцию addScheme, копируется в стек.

Теперь заявление (&(toAdd.at(0)) и подобные утверждения принимают ссылку на то, что находится в положении 0 в векторе. Это означает, что он возвращает указатель на местоположение в стеке.

Как только функция вернется, стек очищается, а указатель на место в стеке содержит мусор.

Чтобы исправить это, пропустите вектор по ссылке или лучше избегайте (&(toAdd.at(0)), потому что это очень странный контракт и, вероятно, никогда не будет работать так, как вы ожидаете.

+0

David - это была действительно самая полезная вещь, которую я когда-либо читал, чтобы ответить на мой вопрос, и первый ответ, который я видел каждый, что 100% ответил на мой вопрос, а не только на помогите мне с моей домашней работой, но чтобы помочь мне учиться. Большое спасибо! – user1311736

+0

Я рад, что смогу помочь –

+0

О-право-Алон. Теперь я вижу, что Дэвид просто редактировал его. Извините, но все же переполнение стека noobie. Благодаря! – user1311736

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