C++ Vector Push_back producing Weird Side Effect - c++

While I was using STL vector to store class objects,, I observed a very weird side effect, where push_back method modifies the Existing Data!
Basically I have a class containing several fields as follows:
class MyClass {
MyClass(std::string s, int i) {
StringValue = s;
IntValue = i;
}
std::string StringValue;
int IntValue;
}
I have a vector that contains the POINTERS to MyClass objects.. and then I am basically pushing back references to objects:
std::vector<MyClass*> MyVector;
MyClass c1("CLASS 1", 1);
MyClass c2("CLASS 2", 2);
MyVector.push_back(&c1);
// Result:
// *MyVector[0] ==> ("Class 1", 1)
MyVector.push_back(&c2);
// Result:
// *MyVector[0] ==> ("Class 2", 2) ??why 2??
// *MyVector[1] ==> ("Class 2", 2)
Do you see the strange result that I got?? I've set breakpoints after each push_back statement,,, and this weird thing happened.
The first push_back statement worked fine. But then the second push_back statement MODIFIED the content of the first element, which doesn't make sense to me..
I'm assuming that it has something to do with me storing References instead of actual objects inside the vector.... but I can't figure out what is wrong.
How can I handle this issue? Any insights?
Thanks
UPDATE:
(simplified code)
MyClass c1("CLASS 1", 1);
MyClass c2("CLASS 2", 2);
MyClass temp;
while (int i=0; i<2; i++) {
temp = c1;
MyVector.push_back(temp);
}
You guys are right,, I get what I'm doing wrong here.. The actual object gets destructed in every loop.. What's the best way to fix this while keeping the current structure?? I'ts hard to explain but I would like to keep this structure (keeping temporary buffer outside the loop).. is this possible?

I'm going to out on a limb and use my psychic powers to derive the real code, rather than the simplified code in the question. Your real code looks like... drumroll...
class MyClass {
// ...
};
void addInstance(std::vector<MyClass*>& MyVector, int i) {
MyClass c("", i);
MyVector.push_back(&c);
}
int main() {
addInstance(MyVector, 1);
addInstance(MyVector, 2);
// ...
}
Here's a working example to demonstrate the problem, which does indeed output "2, 2" (although that's not guaranteed because you're invoking undefined behaviour):
http://ideone.com/PxiUx9
Edit: My psychic powers said "auto variable in a function" when (now that we have the updated question) it was really "auto variable in a loop". Not too far wrong. :-)
You're storing the address of an automatic variable beyond its lifetime, which is not allowed. The address is being re-used on each call, hence each pointer stored is the same, and happens to point to the memory that was last used to store the most recently created instance of MyClass (though that's not guaranteed).
You need to (preferably) store copies of those automatic variables rather than pointers to them, or (less preferably) create them with new and later delete them with delete.
To store copies, you need to use a std::vector<MyClass>. Here's an example of how you might do that: http://ideone.com/4rIijM Note that once your class gets more complex you might need to define a copy constructor, destructor and assignment operator - look up the "rule of three". If you're using C++11, also look up the "rule of five".

For anyone looking for a clear and concise explanation:
Why does an object get destroyed when pushing it to a vector?
You are creating a temporary object:
m_foos.push_back(Foo(a));
// ^^^^^^
Solution:
The function emplace_back is what you want to use:
m_foos.emplace_back(a);
Check out: push_back vs emplace_back
EDIT---
Also, I noted that when compiling with CLion, the error is not fixed. It is also known to be an error on Visual Studio. In other words, be careful with your IDE.

Related

How to model a vector of non-owning raw pointers extracted from unique_ptrs?

Note: Apologies if the title is unclear, I don't quite know how to express the issue in proper terms (improvement suggestions are very welcome).
Code, onlinegdb example of the working version and example of the non-working one first to simplify the explanation:
#include <iostream>
#include <vector>
#include <memory>
class A {
public:
int v = 0;
};
void some_library_function(const std::vector<A*>& objects)
{
// do something to each object without taking ownership
for(auto p : objects)
{
p->v = 42;
}
}
class B
{
public:
std::vector<std::shared_ptr<A>> m_objects; // this is a private field in my actual code
B():m_objects{std::make_shared<A>()}{};
void use_library()
{
std::vector<A*> observer_vector(m_objects.size());
for(int i=0; i<m_objects.size(); i++)
{
observer_vector[i] = m_objects[i].get(); // fails here if I use unique_ptr
}
some_library_function(observer_vector);
}
};
int main()
{
B b;
b.use_library();
std::cout << b.m_objects[0]->v;
return 0;
}
I have a library function that operates on a series of objects of class A passed in via std::vector<A*>. These objects are stored in a field of class B that owns the objects. I would like to model the "owns" part via a vector of std::vector<unique_ptr<A>>, but this makes it impossible to pass the objects down to the library function.
using shared_ptrs works, but I'm worried this is not as expressive as the unique_ptrs with regards to object ownership.
Is there a way to use unique_ptrs in the vector and still be able to use the library function?
You're already doing the right thing. A raw pointer is a perfectly reasonable way to model something with unknown or lacking ownership. You're not storing the vector anywhere, so there is no confusion and no risk.
The only problem here really is that you've had to regenerate the entire vector, which seems like a bit of a waste. Ultimately, if you're set on a vector<unique_ptr<A>> at the source, and you're stuck with vector<A*> at the destination, then there's nothing you can do about that. If the vector is small it doesn't really matter though.
observer_vector[i] = m_objects[i].get(); // fails if with unique_ptr because of operator= being deleted
No, that should be valid. You're just assigning a raw pointer.

A vector member is reset and unaccessible

I have two projects, one basic client and a dynamic library.
Here's what happens in the client:
int main()
{
Scrutinizer scru;
scru.Scrutinize();
return 0;
}
In the DLL, The Scrutinizer class is as such (__declspec(dllexport) and such omitted for Clarity)
Header
class ProcessesGenerator;
class Scrutinizer
{
public:
Scrutinizer();
~Scrutinizer();
ProcessesGenerator *ProcGenerator
void Scrutinize();
};
The forward declaration of ProcessesGenerator was 'mandatory' for me to avoid some kind of circular reference.
Constructor in .cpp file
Here is how I initialize it:
Scrutinizer::Scrutinizer()
{
ProcGenerator = &ProcessesGenerator();
}
More about this ProcessesGenerator class:
Header
class ProcessesGenerator
{
public:
ProcessesGenerator();
~ProcessesGenerator();
WinFinder winFinder;
std::vector<std::string> fooCollec;
void GenerateProcesses();
};
ProcessesGenerator.cpp
Constructor:
ProcessesGenerator::ProcessesGenerator()
{
//winFinder = WinFinder();//problem will be the same with or without this line
fooCollec = std::vector<std::string>{"one", "two", "three"};
}
A breakpoint in the constructor shows that the vector is initialized with the chosen values.
Problematic function:
void ProcessesGenerator::GenerateProcesses() {
std::string foo = "bar";
fooCollec = std::vector<std::string>{};//read access violation
fooCollec.push_back(foo);//read access violation
winFinder.SomeVector= std::vector<std::string>{};//read access violation
}
Once there, I Can see that the size of vector is reset to 0. Any attempt to re-initialize it, or to push an element results in read access violation .Same with the vecotr member of its WinFinder member. I guess the flaw is obvious, but I really don't get it,
Thanks!
Your problem is with
Scrutinizer::Scrutinizer()
{
ProcGenerator = &ProcessesGenerator();
}
What you are doing is taking the address of a temporary object. That object will be destroyed and the end of that line and you will be left with a pointer that doesn't point to a valid object.
The old way to fix it would be to use
Scrutinizer::Scrutinizer()
{
ProcGenerator = new ProcessesGenerator();
}
But now you have to implement the copy constructor, copy assignment operator, and the destructor. Since you have a modern compiler what you can do instead is make ProcGenerator a std:unique_ptr<ProcessesGenerator> and then Scrutinizer() becomes
Scrutinizer::Scrutinizer() : ProcGenerator(make_unique<ProcessesGenerator>()) {}
I would also like to add that &ProcessesGenerator(); should not even compile. Unfortunately MSVS has a non-standard extension that allows this to compile. You can turn on the /Za compiler option (enforce ANSI compatibility) and then you should get an error like
error C2102: '&' requires l-value
The line ProcGenerator = &ProcessesGenerator(); makes a temporary ProcessesGenerator, takes its address and then puts it in your ProcGenerator pointer. The temporary is then destroyed, leaving garbage.
You probably wanted to be allocating it on the heap ProcGenerator = new ProcessesGenerator; but even in that case I would strongly suggest using unique_ptr instead of a raw pointer.

c++ vector without pointers

I have a std::vector<Enemy*> enemies and when i create a new Enemy i do enemies.push_back(this). This works for what i'm doing, but i'm wondering if there is a way to have the vector not need pointers to the enemies. I've tried just std::vector<Enemy> but it seems to cause a bunch of problems i can't figure out.
ie. - had to change to enemies.push_back(*this), and it caused some linker errors for some reason.
looping through with the following works, but removing the pointers creates issues:
void Enemy::updateEnemies(sf::RenderWindow &window) {
for(std::vector<Enemy*>::iterator it = enemies.begin(); it < enemies.end(); it++) {
(*it)->update(window);
}
}
Wondering if someone could point me in the direction of using a vector without pointers and loop through it, updating the objects inside it with the same function..
everbody is saying it in comments - but its the answer
use smart pointers
if you dont know how to do that then google
You life is much easier, safer, faster,...
And they are really easy to use - the main trick with using them is to trust them and dont try to get clever or 'help' them
My practice is to make sure the class implements (and makes public) all of the following: a default constructor, a copy constructor, an assignment operator, and a destructor. Then there's no problem with things like std::vector<Enemy>. (The default constructor isn't even necessary for vectors, but can be handy for various other things.)
One caveat, though: when you push_back() an Enemy into your vector, it's actually a copy of the original instance that gets stored. This raises a few gotchas: first, changes to the original (e.g. to the member data of the variable e in the main() scope of my example below) will not affect the copy stored in the vector. If you're accustomed to working with vectors-of-pointers, this may be surprising. Second, the implicit construction of copies and the copying of member data will take time, which may or may not have a significant effect on performance. Third, implicit construction and copying may trigger side-effects (you should simply avoid these in your design, wherever possible).
Here's an example:
#include <vector>
#include <iostream>
class Enemy
{
public:
Enemy() : mEvilness( 1 ) {} // default (i.e. parameterless) constructor
Enemy( const Enemy& other ) { Copy( other ); } // copy constructor
Enemy& operator=( const Enemy& other ) { return Copy( other ); } // assignment operator
~Enemy() {} // destructor
Enemy( int evilness ) : mEvilness( evilness ) {} // standard constructor
void Gloat( void ) const
{
std::cout << "muahaha";
for( int i = 0; i < mEvilness; i++ ) std::cout << "ha";
std::cout << "!\n";
}
int mEvilness;
private:
// common helper method for copy constructor and assignment operator:
Enemy& Copy( const Enemy& other )
{
mEvilness = other.mEvilness; // make copies of any other member data here
return *this;
}
};
typedef std::vector< Enemy > EnemyHorde;
void AllGloat1( const EnemyHorde& h ) // doesn't matter if you pass by reference...
{
for( EnemyHorde::const_iterator it = h.begin(); it != h.end(); it++ )
it->Gloat();
}
void AllGloat2( EnemyHorde h ) // ...or value (but this will take more CPU time)
{
for( EnemyHorde::const_iterator it = h.begin(); it != h.end(); it++ )
it->Gloat();
}
int main( int argc, const char* argv[] )
{
EnemyHorde h;
Enemy e( 1 );
h.push_back( e );
h.push_back( Enemy( 2 ) ); // even transient Enemy instances get copied and stored
h.push_back( Enemy( 3 ) );
AllGloat1( h );
std::cout << "\n";
e.mEvilness++; // this will have no effect on the output because h contains a *copy* of e
AllGloat2( h );
return 0;
}
If you want a well-founded answer you have to go one step back - to the design. As far as i see the Enemy objects are registering themselves via constructor in a kind of global list. So far so good.
But how these object are produced ? In this example in Enemy can be construct everywhere
On the stack as local
By new (smartpointer)
As an element in a vector, list, deque ...
...
Depending on this, the Enemy-object cant do any reliable statements about its storage. But one thing that all objects share and what is always accessible from inside the object - is the address ('this'). So the solution via pointer is the only solution that is universal for all constructed Enemy-objects. (References are in this context also "a kind of pointer", and other more complicate constructs may also rely on pointers).
A std::vector cant work because you get 2 different objects. To change one of them does not effect the other. That wont work. And it is not possible to switch to smart pointers without changing your design.
There are 2 common solutions:
Managing the listing from 'inside' Enemy in a generally way like in the given example. Expandable with more features like auto delete entries via destructor.....
Managing the listing from 'outside'. Enemy-objects dont register themselves, the generator of the Enemy-objects is responsible for to do it proper (the design pattern 'factory' is a good solution in this case). And you can use smart pointers what is a good idea in most cases.
There are also some more solutions (including some good solutions) unmentioned, they exceed the scope of the question.
You don't need pointers (most of the time) in C++.
A copy will be made when using the std::vector::push_back() method.
Example:
Enemy evil_wizard;
std::vector<Enemy> enemy_container;
enemy_container.push_back(evil_wizard);
Enemy Evil_knight;
enemy_container.push_back(Evil_knight);
Enemy pink_elephant;
enemy_container.push_back(pink_elephant);

Vector push_back error

So this is the situation.
I have a class
Class L_FullQuote
{
private:
vector<int> time;
..
}
and
Class B
{
L_FullQuote *Symbols[100];
void handle message()
}
Inside handle msg
i have this statement
Symbols[i]->time.push_back(2);
the code builds fine..but when i use the generated dll. the application just crashes..sometimes it takes me to a nxt poiner error in vector..but mostly the whole application just crashes.
It works fine without that line.
Please help
Thanks
You're already using vector, so why not take it one step further? Using std::vector will allow you to focus on writing your functionality, rather than worrying about memory management.
This example differs slightly from what you originally posted. Your original question class B has an array of 100 pointers that each must be initialized. In the example below, we create a std::vector of L_FullQuote objects that is initially sized to 100 objects in the constructor.
class L_FullQuote
{
public:
vector<int> time;
};
class B
{
public:
// Initialize Symbols with 100 L_FullQuote objects
B() : Symbols(100)
{
}
std::vector<L_FullQuote> Symbols;
void handle_message()
{
Symbols[i].time.push_back(2);
// other stuff...
}
};
L_FullQuote *Symbols[100];
Here you declare an array of pointer to L_FullQuote, but you never initialize any of the pointers, so when you call:
Symbols[i]->...
You are dereferencing an invalid pointer. Also note that you have declared time as private (though your code wouldn't even compile this way, s B as a friend of A I assume?)
Simply declaring an array of pointers does not initialize each element to point to a valid object. You need to initialize each one, something like:
for(int i = 0; i < 100; ++i) {
Symbols[i] = new L_FullQuote();
}
Only then do you have an array full of valid pointers. Don't forget to deallocate them though!
time is private member of class L_FullQuote, from class B you don't have access to that field

Creating function pointers to functions created at runtime

I would like to do something like:
for(int i=0;i<10;i++)
addresses[i] = & function(){ callSomeFunction(i) };
Basically, having an array of addresses of functions with behaviours related to a list of numbers.
If it's possible with external classes like Boost.Lambda is ok.
Edit: after some discussion I've come to conclusion that I wasn't explicit enough. Please read Creating function pointers to functions created at runtime
What I really really want to do in the end is:
class X
{
void action();
}
X* objects;
for(int i=0;i<0xFFFF;i++)
addresses[i] = & function(){ objects[i]->action() };
void someFunctionUnknownAtCompileTime()
{
}
void anotherFunctionUnknowAtCompileTime()
{
}
patch someFunctionUnknownAtCompileTime() with assembly to jump to function at addresses[0]
patch anotherFunctionUnknownAtCompileTime() with assembly to jump to function at addresses[1]
sth, I don't think your method will work because of them not being real functions but my bad in not explaining exactly what I want to do.
If I understand you correctly, you're trying to fill a buffer with machine code generated at runtime and get a function pointer to that code so that you can call it.
It is possible, but challenging. You can use reinterpret_cast<> to turn a data pointer into a function pointer, but you'll need to make sure that the memory you allocated for your buffer is flagged as executable by the operating system. That will involve a system call (LocalAlloc() on Windows iirc, can't remember on Unix) rather than a "plain vanilla" malloc/new call.
Assuming you've got an executable block of memory, you'll have to make sure that your machine code respects the calling convention indicated by the function pointer you create. That means pushing/popping the appropriate registers at the beginning of the function, etc.
But, once you've done that, you should be able to use your function pointer just like any other function.
It might be worth looking at an open source JVM (or Mono) to see how they do it. This is the essence of JIT compilation.
Here is an example I just hacked together:
int func1( int op )
{
printf( "func1 %d\n", op );
return 0;
}
int func2( int op )
{
printf( "func2 %d\n", op );
return 0;
}
typedef int (*fp)(int);
int main( int argc, char* argv[] )
{
fp funcs[2] = { func1, func2 };
int i;
for ( i = 0; i < 2; i++ )
{
(*funcs[i])(i);
}
}
The easiest way should be to create a bunch of boost::function objects:
#include <boost/bind.hpp>
#include <boost/function.hpp>
// ...
std::vector< boost::function<void ()> > functors;
for (int i=0; i<10; i++)
functors.push_back(boost::bind(callSomeFunction, i));
// call one of them:
functors[3]();
Note that the elements of the vector are not "real functions" but objects with an overloaded operator(). Usually this shouldn't be a disadvantage and actually be easier to handle than real function pointers.
You can do that simply by defining those functions by some arbitrary names in the global scope beforehand.
This is basically what is said above but modifying your code would look something like this:
std::vector<int (*) (int)> addresses;
for(int i=0;i<10;i++) {
addresses[i] = &myFunction;
}
I'm not horribly clear by what you mean when you say functions created at run time... I don't think you can create a function at run time, but you can assign what function pointers are put into your array/vector at run time. Keep in mind using this method all of your functions need to have the same signature (same return type and parameters).
You can't invoke a member function by itself without the this pointer. All instances of a class have the function stored in one location in memory. When you call p->Function() the value of p is stored somewhere (can't remember if its a register or stack) and that value is used as base offset to calculate locations of the member variables.
So this means you have to store the function pointer and the pointer to the object if you want to invoke a function on it. The general form for this would be something like this:
class MyClass {
void DoStuf();
};
//on the left hand side is a declaration of a member function in the class MyClass taking no parameters and returning void.
//on the right hand side we initialize the function pointer to DoStuff
void (MyClass::*pVoid)() = &MyClass::DoStuff;
MyClass* pMyClass = new MyClass();
//Here we have a pointer to MyClass and we call a function pointed to by pVoid.
pMyClass->pVoid();
As i understand the question, you are trying to create functions at runtime (just as we can do in Ruby). If that is the intention, i'm afraid that it is not possible in compiled languages like C++.
Note: If my understanding of question is not correct, please do not downvote :)