Problem inserting into Vector

W

wutongjoe

Hi,I had a problem while I was doing the assignment .the code is like
below(not exact):


//======================================

class Buyer
{
private:
int _product;

public:
//Buyer(void){ _product=-1;);
int get_product(void);
Buyer( int n ){ _product = n;};
};

int Buyer::get_product(void){
return _product;
};

std::vector<Buyer *> buyer_queue;

int main( int argc, char *argv[] )
{
for(;;){
int i=int(1+rand()%10);
Buyer b=Buyer(i);

buyer_queue.push_back(&b);
printf("\nB[%d]",(*buyer_queue[buyer_queue.size()-1]).get_product());

for (int j=0;j<buyer_queue.size();j++){
printf("\t\n looped [%d]",(*buyer_queue[j]).get_product());

}
usleep(1000000);
}
}

//====================================


the problem is in the for loop,why it outputs the same value for
member"product" of each Buyer?
 
R

red floyd

Hi,I had a problem while I was doing the assignment .the code is like
below(not exact):


//======================================

class Buyer
{
private:
int _product;

public:
//Buyer(void){ _product=-1;);
int get_product(void);
Buyer( int n ){ _product = n;};
};

int Buyer::get_product(void){
return _product;
};

std::vector<Buyer *> buyer_queue;

int main( int argc, char *argv[] )
{
for(;;){
int i=int(1+rand()%10);
Buyer b=Buyer(i);

buyer_queue.push_back(&b);
printf("\nB[%d]",(*buyer_queue[buyer_queue.size()-1]).get_product());

for (int j=0;j<buyer_queue.size();j++){
printf("\t\n looped [%d]",(*buyer_queue[j]).get_product());

}
usleep(1000000);
}
}

//====================================


the problem is in the for loop,why it outputs the same value for
member"product" of each Buyer?

Don't see any of the "Miranda" functions.

Provide a default constructor, copy constructor, and assignment operator.

Also, you want to call srand() before you call rand().
 
D

DaKoadMunky

Buyer b=Buyer(i);
buyer_queue.push_back(&b);

The address you are storing is the address of a local variable with automatic
storage duration. That variable is being destroyed at the end of the for loop
in which it is declared and thusly your vector contains a pointer to an object
that has been destroyed.

However, in my runtime environment every pass through the loop results in that
variable being reconstructed at the same memory location as the last pass
through the loop. As a result all the pointers stored in the vector point to
the same object and at the time those pointers are accessed they are infact
pointing to a valid object.

Is there some reason you just didn't use std::vector<Buyer>?
 
W

wutongjoe

DaKoadMunky said:
The address you are storing is the address of a local variable with automatic
storage duration. That variable is being destroyed at the end of the for loop
in which it is declared and thusly your vector contains a pointer to an object
that has been destroyed.

However, in my runtime environment every pass through the loop results in that
variable being reconstructed at the same memory location as the last pass
through the loop. As a result all the pointers stored in the vector point to
the same object and at the time those pointers are accessed they are infact
pointing to a valid object.

Is there some reason you just didn't use std::vector<Buyer>?
declare buyer as a gloabl variable would do ?if I want to insert many
buyers with random product.
 
D

DaKoadMunky

declare buyer as a gloabl variable would do ?if I want to insert many
buyers with random product.

The object passed to vector<T>::push_back will be copied using the T copy
constructor. It is the copy that becomes part of the controlled sequence.

vector<Buyer> buyers;

for(int i=0;i<10;++i)
{
Buyer buyer(i);
buyers.push_back(buyer);
}

At this point the vector contains 10 elements that are copies of the elements
that were arguments to vector<T>::push_back.
 
R

Richard Herring

red floyd said:
Hi,I had a problem while I was doing the assignment .the code is like
below(not exact):
//======================================
class Buyer
{
private:
int _product;
public:
//Buyer(void){ _product=-1;);
int get_product(void);
Buyer( int n ){ _product = n;};
};
int Buyer::get_product(void){
return _product;
};
std::vector<Buyer *> buyer_queue;
int main( int argc, char *argv[] )
{
for(;;){
int i=int(1+rand()%10);
Buyer b=Buyer(i);
buyer_queue.push_back(&b);
printf("\nB[%d]",(*buyer_queue[buyer_queue.size()-1]).get_product());
for (int j=0;j<buyer_queue.size();j++){
printf("\t\n looped [%d]",(*buyer_queue[j]).get_product());

}
usleep(1000000);
}
}
//====================================
the problem is in the for loop,why it outputs the same value for
member"product" of each Buyer?

Don't see any of the "Miranda" functions.

Provide a default constructor, copy constructor, and assignment operator.

Why? The class doesn't use pointers or manage resources, so the
compiler-generated copy and assignment will have the correct semantics.
Writing your own, unnecessarily, is just another opportunity to add
errors.
Also, you want to call srand() before you call rand().

The real problem is that every entry in the vector is a pointer to
(effectively) the *same* object, 'b'. So no matter which element of the
vector you look at, you see the last value assigned to b.
 
H

Howard

declare buyer as a gloabl variable would do ?if I want to insert many
buyers with random product.

No. Simply store Buyer objects instead of pointers to them. Then each
object in the vector will be unique, because push_back will make a copy of
the object and store that. Then when you re-use the object, it will be
different.

Also, you should use

Buyer b(i);

instead of

Buyer b=Buyer(i);

There's no need for the assignment. (Perhaps you were thinking of "Buyer* b
= new Buyer(i);"?)

-Howard
 
R

red floyd

Richard said:
[ reply to my incredibly dumb comment redacted]

You're right... I missed the fact that he was storing *pointers*. I've
been bitten by bad or missing Miranda functions with vectors before, so
that's why I suggested that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top