C++ Object references in loop [duplicate] - c++

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C++ Object references in loop cycle
I'm trying to create different objects of the same type using a loop, and then storing a pointer to each specific object in a linked list.
The problem is, each time an object is instanciate, its pointer return the same memory adress, wich doesn't allow me to differentiate each individual object in that list.
I'm trying to create different objects of the same type using a loop, and then storing a pointer to each specific object in a linked list. The problem is, each time an object is instanciate, its pointer return the same memory adress, wich doesn't allow me to differentiate each individual object in that list.
Any solution to that? Thanks
I have a function with the following:
Data dt(10,10,2010);
int p=0;
ifstream fx;
fx.open("utilizadores.txt",ifstream::in);
if(!fx)
{cout << "FX. nao existe!" <<endl;}
string linha;
string nLugar;
int iD=1;
while(!fx.eof())
{
getline(fx,linha,'\n');
Utilizador* user;
if(linha.find(',')==-1 && linha.size()>1)
{
cout<<"Entrou no vector"<<endl;
string nlugar(linha.substr(0, linha.size()));
nLugar=nlugar;
}
else
{
int inic=0;
int pos=linha.find(',',inic);
string nick(linha.substr(inic,pos-inic));
pos++;
inic=pos;
pos=linha.find(',',inic);
string email(linha.substr(inic,pos-inic));
user=new Utilizador(dt,iD,nick,email);
cout<<&user<<endl;
cout<<user->clone()<<endl;
}
fx.close();
}
The linked list is declared in the class statement
Any solution to that?
Thanks

cout<<&user<<endl;
This does not print the address of the object, but the address of the pointer to the object. This pointer will always be in the same location on the stack for any given run of the program and thus will yield the same address.

do you have something like?
std::list<myobjecttype*> lst;
for (..).
{
myobjecttype* a = new myobjecttype;
lst.push_back(a);
}

Related

pointer returned to an object turns null after function returns address

I am new to CPP and I am writing a program as an assignment to simulate a train path system that includes destinations and starts using object oriented programming .
I have 2 classes as shown below (there is a a passenger class but it is not relevant ) :
class Train
{
public:
int cooldown_time;
int travel_time;
int time_since_movement;
int id;
class Station *start;
class Station *destination;
vector<Passenger *> current_passengers;
string status;
void add_train(vector<string> commands, vector<Station> stations, vector<Train> &trains)
{
travel_time = stoi(commands[THIRD_PART + 1]);
cooldown_time = stoi(commands[THIRD_PART + 2]);
status = TSTATUS1;
start = station_search(stations, commands[SECOND_PART]); // this is where the problem happens
destination = station_search(stations, commands[THIRD_PART]);
id = stations.size();
}
};
class Station
{
public:
int tuffy_price;
string city_name;
vector<Passenger *> current_passengers;
vector<Train *> current_trains;
int id;
void add_station(vector<Station> &stations, vector<string> &commands)
{
tuffy_price = stoi(commands[THIRD_PART]);
city_name = commands[SECOND_PART];
id = stations.size();
}
};
I have a search function dedicated to finding the start and destination based off a command that user enters for example :the user enters "add_train cityname1 cityname2 <cooldown_time> <travel_time>". my program detects the city names and searches a vector I have named stations with a key that is the city name and returns a pointer (because of the complications in memory behavior in a function , i set it to pointer) to that station-object .
the function is as below :
Station *station_search(vector<Station> stations, string key)
{
Station *dummy;
for (int i = 0; i < stations.size(); i++)
{
if (stations[i].city_name == key)
{
return &stations[i];
}
}
return dummy;
}}
my problem is with my search function's weird behavior , when I debug the program I see the function find the correct station object and return a pointer to it ,but when the execution returns to the constructor function it randomly (maybe not randomly ) turns the first pointer relating to the start station to null and replaces the values inside with garbage ones.
but after the function searches for the destination station it does not do this and the execution is correct.
Could someone explain why this error is occurring?
My guess is that I have not understood local variables and pointer returns well enough and I have committed a rookie mistake somewhere but I don't seem to find it .
PS: I did not include the full code as it's too long I can include it by attaching a file ,comment down if it's necessary.
Station *station_search(vector<Station> stations, string key)
If you take a closer look here, you will see that the stations parameter is passed by value, which means that after this function returns, this stations parameters will get destroyed. It will be no more. It will cease to exist. It will become an ex-parameter.
However this station_search returns a pointer to some value in this vector. Therefore, rules of logic dictate that it will return a pointer to a destroyed object. Attempting to dereference that pointer, in any way, becomes undefined behavior.
Your other class methods receive parameters by reference, so you must already understand the difference between passing parameters by value vs. by reference, so you should simply do the same here.
Here you are passing a copy of the vector, which is destroyed when the function returns. Additionally, if the key is not found an uninitialized pointer is returned.
Station *station_search(vector<Station> stations, string key)
{
for (Station &station : stations)
{
if (stations.city_name == key)
{
// Pointer becomes invalid when you leave.
// Accessing this pointer will cause undefined behavior.
return &station;
}
}
// This would always cause undefined behavior as dummy was not initialized.
return nullptr;
}
You should pass in a reference and initialize dummy:
Station *station_search(vector<Station> &stations, string key)

Having problem in dereferencing the vector

I am creating a grid game in which each box in the grid is a district and represents some people along with their specific ID.
Now I have a function here which locates where the exact person is in the grid in particular box.
Here is my function.
bool where(int id, int &row, int &col)const
{
person* per;
for(int i=0;i<alive.size();i++)
{
std::cout<<alive[i]<<std::endl; //This is just for testing the person number
if (alive[i]->person_id == id)
{
p = alive[i];
break;
}
}
}
My Question: The test code std::cout<<alive[i]<<std::endl; is always printing the address of the number. I tried many things but I couldn't figure it out.
Edit: Here alive is a vector
Can anyone please help me.
Consider this line in your code: if (alive[i]->person_id == id). The fact that it uses -> rather than . indicates that alive isn't a vector of some struct/class, but is rather a vector of pointers (or potentially some other object that acts like a pointer) to some struct/class. As such, to print the actual object, do std::cout<<*alive[i]<<std::endl; (note the added *).

Segmentation fault while accessing an object inside a vector of object

I am having a segmentation fault while trying to access an object stored inside a vector. I have a Survey which consists of Processes. Each process consists of questions. So the Survey Object contains a vector or Processes and each process object contains a vector of questions. The class definitions are as follows:
class Survey {
private:
...
vector <Process> survey_processes;
....
public:
......
vector<Process> getSurveyProcesses()
{ return survey_processes; }
void addProcessObj(Process obj)
{ survey_processes.push_back(obj);}
.....
};
class Process
{
private:
....
vector<Question> proc_questions;
....
public:
...
vector<Question> getProcessQuestions()
{ return proc_questions;}
void addQuestionObj(Question obj)
{ proc_questions.push_back(obj); }
.....
};
class Question {
private:
int quesnum;
int answer;
...
public:
Question (int c_ques, int c_ans)
{
quesnum = c_ques;
answer = c_ans;
}
int getQuestionID()
{
return quesnum;
}
int getAnswer()
{
return answer;
}
...
};
As the new process object is created, I store it in the vector of Processes and for each Process Object, I push the Question Object in the vector of Questions. For the survey Object, I want to get each Process from the Process Vector and for each Process Object, get each question object and print it.
I can access the Process Objects and print them successfully by using following code.
cout << ((survey_obj.getSurveyProcesses()).back()).getProcessID() << endl;
When I try to extract the question object from inside the Process vector, it gives me a segmentation error. I believe I am making some syntax error while trying to access the object. How do I access the question Object embedded inside a vector of Questions for a given Process Object which is inside a vector of process objects for a given survey object?
Here is the relevant part of the code where the segmentation fault occurs.
int procnum = 0;
for (unsigned i = 11; i < all_words.size()-1; ++i)
{
vector<string> v;
string s = all_words.at(i);
stringstream ques_stream(s);
int ques_num;
ques_stream >> ques_num;
ques_stream.ignore();
// if process object already exists, do nothing. Otherwise create a new process object and add it to the survey object
if (procnum == ques_num)
;
else
{
Process proc_obj(ques_num);
survey_obj.addProcessObj(proc_obj);
procnum = ques_num;
}
string ques_strng;
ques_stream >> ques_strng;
ques_stream.ignore();
Question ques_obj(ques_strng);
// objective: put the new question object in the question vector of the last process object from the process vector of the survey object
cout << ((survey_obj.getSurveyProcesses()).back()).getProcessID() << endl;
Process current_proc_obj = (survey_obj.getSurveyProcesses()).back();
cout << " Current Process : " << current_proc_obj.getProcessID() << endl;
Question current_question_obj = (current_proc_obj.getProcessQuestions()).back();
((survey_obj.getSurveyProcesses()).back()).addQuestionObj(ques_obj);
**// this is where the segmentation fault occurs when i try to get the last object from process vector of the survey and for that object get the last element of the question vector. print the question id of this question object
cout << " Current Question : " << ((((survey_obj.getSurveyProcesses()).back()).getProcessQuestions()).back()).getQuestionID() << endl;**
cout << " Current Process Question : " << ((current_proc_obj.getProcessQuestions()).back()).getQuestionID() << endl;
}
I tried running the gdb debugger but it only tells me that error occurs while trying to access the questionID. I still do not know what i am doing wrong and any help would be greatly appreciated.
((survey_obj.getSurveyProcesses()).back()).addQuestionObj(ques_obj);
_______________copy^, _copy^ - ^_______added to copy
Since you are returning vectors by value, not reference, you are adding ques_obj to a temporary local vector, not the one held by survey_obj.
The crash is occurring because you're accessing past the end of the (empty) vector, since nothing got added to it.
One way to fix this is to return the class member vector by reference, instead of by value. (Since by value can be though of as a copy of the variable.)
class Survey {
private:
vector <Process> survey_processes;
public:
vector<Process>& getSurveyProcesses()//<--ampersand indicates return by reference
{ return survey_processes; }
};
Now, when you try this:
((survey_obj.getSurveyProcesses()).back()).addQuestionObj(ques_obj);
______^ this is the vector inside the Survey class,
not a copy
Fortunately, std::vector::back also returns by reference, so the ques_obj gets added to the object held by the vector, held by the Survey object - no local, temporary copies involved! Later, when you go to query that question, you'll find it in the place you expected it.
Two final notes: 1) You should decide whether you should also return the process_questions by reference; 2) If you had used the ability for vector to tell you how many elements it contains, instead of just assuming that back() would work, you would have found this problem earlier. :)

C++ Object references in loop cycle

I'm trying to create different objects of the same type using a loop, and then storing a pointer to each specific object in a linked list. The problem is, each time an object is instanciate, its pointer return the same memory adress, wich doesn't allow me to differentiate each individual object in that list.
Any solution to that? Thanks
I have a function with the following:
Data dt(10,10,2010);
int p=0;
ifstream fx;
fx.open("utilizadores.txt",ifstream::in);
if(!fx)
{cout << "FX. nao existe!" <<endl;}
string linha;
string nLugar;
int iD=1;
while(!fx.eof())
{
getline(fx,linha,'\n');
Utilizador* user;
if(linha.find(',')==-1 && linha.size()>1)
{
cout<<"Entrou no vector"<<endl;
string nlugar(linha.substr(0, linha.size()));
nLugar=nlugar;
}
else
{
int inic=0;
int pos=linha.find(',',inic);
string nick(linha.substr(inic,pos-inic));
pos++;
inic=pos;
pos=linha.find(',',inic);
string email(linha.substr(inic,pos-inic));
user=new Utilizador(dt,iD,nick,email);
cout<<&user<<endl;
cout<<user->clone()<<endl;
}
fx.close();
}
The linked list is declared in the class statement
cout<<&user<<endl;
should be:
cout<<user<<endl;
&user is address of local variable Utilizador*, which remains the same. user variable value itself is the pointer you need, and it should be different on every iteration.
This line
cout<<&user<<endl;
prints the address of a pointer to an object. user is itself a pointer to the object you're creating. To print the address of your object, you meant to write
cout<<user<<endl;
Although it'll be a new object each time, the variable user is always in the same place. You can add the value of user to your list, and it will indeed be different each time.
"&user" return address of pointer, that contains references to objects.

Vector of object pointers containing vectors end up pointing to same object

I am storing multiple objects in a vector of pointers to these objects, like so, in C++:
vector<Host *> somevector;
I then initialize each item like this:
somevector.push_back(new Host(x));
The object takes an initializing argument.
As I read through data (strings) and end up with a list of object pointers, I add them to an internal vector inside the object itself:
somevector.at(i)->add(string data);
However, it appears that all the data have been added to the same object, and even though the objects have different names, their internal vector that stores this data are identical.
I searched various keywords to solve this and I think it is an issue with a copy constructor (I currently am using default). How do I account for the vector inside the object that I am copying? Do I have to make the vector in the object a field so that a new one is created in the copy constructor?
EDIT:
I've replicated the code for the object class:
vector<string> v;
Host::Host(string _x): x(_x)
{
}
Host::~Host()
{
}
string Host::name()
{
return x;
}
string Host::link(int r)
{
int i = r % v.size();
return v.at(i);
}
void Host::add(string data)
{
v.push_back(data);
}
So I am using this vector inside the host object to store a bunch of strings. Then, when I call link from my main program, I pass it a random number, and I want to get a random string from the list inside the object. However, my link() calls are coming back with strings that should not have been stored into the object.
From what I can see from the example code you have posted 'v' isn't a member object of Host. So calls to Host::add are simply pushing back to a globally available vector. Is this perhaps where your problem is?