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.
Related
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)
I'm writing part of a customer database that handles making new customers and selling them items.
In "Customer.h", I have the struct:
struct Customer {
String name;
int bottles;
Customer(String);
Customer(void) { name = "__invalid__"; }
};
I have a class in the file "CustomerDB.h"
class CustomerDB {
private:
Customer* data; // an array of Customer objects (allocated on the heap)
int capacity; // size of the array on the heap
int length; // number of valid customers actually in the array
public:
CustomerDB(void);
There's a constructor, in "CustomerDB.cpp"
Customer::Customer(string name) {
this->bottles = 0;
this->name = name;
}
I create *an object in another function (which is in "CustomerDB.cpp")
Customer& CustomerDB::operator[](string name) {
Customer Customer(name);
return Customer;
And there's an object of CustomerDB:
CustomerDB database; (Which is in another cpp file which handles the purchases).
The string input works. The object is created. There's no issues there.
So I have 2 problems, one of which is because of the other.
I need to make a new non-Local Customer object in this function (stored into the non-Local Database), and
Return the reference to it. But the constructor I just called doesn't give me a reference. It just makes it, as it should.
I'm unintentionally making a local object instead of one that's added to the "main" database. As a result, the reference is nothing useful.
If I try return Customer; it says that "Customer does not refer to a value."
Any help/advice is appreciated.
I need to return the address of this freshly made Customer
No, you need to return a reference to it.
but the constructor I just called
You never call constructors. You declared an object.
doesn't give me an address. How do I find/obtain this new Customer and return its address?
You take the address of an object like this:
return &Customer;
But to return a reference, it's simply:
return Customer;
But this isn't going to work!
You'd be returning a reference to a local variable. It's about to go out of scope, leaving the reference dangling.
So, you need to rethink your choices with this design.
I have created an object of a certain class. The class is "Node" and it has an attribute of CString strName. The value of this variable can be retrieved with a method of Node: CString Node::GetName(), which just returns the name of the variable.
In the following method I instantiate this:
Node* UpperClass::GetObject(CString value) {
Node retObject;
retObject.strName = value;
Trace(retObject.strName); // Prints argument to trace file - this prints the value of strName fine
return &retObject;
}
Then I run this method in a second class:
Node* LowerClass::Get() {
Node *pReturn = instanceOfUpperClass.GetObject();
Trace(pReturn->GetName()); // This trace just prints blank...
return *(&pReturn);
}
As you can see by the code comments, it seems to lose the value when it is passed to the second method. I've attempted to research this but am having some real trouble getting to grips with why.. can anyone help?
As an aside, if one is wondering about the return value of the second method, I am intending to past the resultant pointer to a third function where I utilise it for processing (messy, I know, but I inherited the code and have no choice); just in case that has any bearing on the answer.
Thanks in advance!
int this method:
Node* UpperClass::GetObject(CString value) {
Node retObject;
retObject.strName = value;
Trace(retObject.strName); // Prints argument to trace file - this prints the value of strName fine
return &retObject; // <-- Undefined Baaviour
}
you are returning pointer to local object, which is destroyed once this method ends. You should create retObject dynamically, and return pointer to it, or better put this pointer into shared_ptr<>.
The Node retObject is a local variable when you go out of scope of the function GetObject any use of the object is undefined. And in this case you return a pointer to that object.
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);
}
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?