Class vector c++ issue - c++

I'm having some trouble with vector class. For some reason, yet to be found :P, I can't insert any objects to my vector. I've tried vector, map, deque, etc, but they all have the same weird result.
The object that I want stored is a class with 2 std::string in it. Here's some code to explain my point:
vector<DnsAddress> * dnss = new vector<DnsAddress>;
for(int i = 0; i < ns.size(); i++){
DnsAddress dn;
dn.SetRecord1(record1);
dn.SetRecord2(record2);
cout<<dn.GetRecord1()<<" : "<<dn.GetRecord2()<<endl; //this works, so it is inserting info to the object
dnss->push_back(dn);//this is where it begins to fail...
cout<<dnss->at(i).GetRecord1()<<" : "<<dnss->at(i).GetRecord2()<<endl;//doesn't work
DnsAddress a = dnss->at(0);//this way doesn't work either...
cout<<"dns: "<<a.GetRecord1()<<endl;
}
I'm sure there must be a rookie mistake.. I hate when those happen.. They consume me some time to find out.
Can someone give a hand with this?
I appreciate it :)
To claify:
There are no errors... It works without problem... but the info in the vector gets counted(.size() function tells me the number of inserted objects) but when you try to access it, nothing is shown... But no error is raised
This is class DnsAdress:
class DnsAddress {
public:
DnsAddress();
DnsAddress(const DnsAddress& orig);
virtual ~DnsAddress();
void SetRecord2(string record2);
string GetRecord2() const;
void SetRecord1(string record1);
string GetRecord1() const;
private:
string record1;
string record2;
};

This is just a guess since you didn't show your class DnsAddress or tell us what the error was.
My guess:
Your class doesn't have a copy constructor (compile time error) or
The copy constructor isn't making a correct copy (run time misbehavior).

I'll bet your DnsAddress class needs a copy constructor. This effectively gets invoked when you call push_back on a vector of non-pointer elements.
Edit: Looks like you do have a copy constructor. Actually if you just deleted the copy constructor, the default one would work fine. If you still want to implement it manually, you'll need to assign record1 and record2 to to orig.record1 and orig.record2 in your copy constructor implementation.

Related

Assign object even though assignment operator is implicitly deleted

I'm working on an assignment that uses OMNeT++, Veins/Sumo. Although my question is not completely related to it, it might add some context.
I'm familiar with programming, but having a little bit of trouble wrapping my head around the whole
The idea is that there is a network of cars, and all these cars are talking to eachother using messages. A message inlcudes the vehicle name, but also information about the current position/mobility of the car. This is where TraCIMobilitycomes in.
Ideally I would like to have all this information stored in the original class in the message, but I am running into some issues.
pointer/memory address idea when working with classes.
class InterVehicleMessage : public ::veins::DemoSafetyMessage
{
protected:
::omnetpp::opp_string vehicleName;
veins::TraCIMobility vehicle_mobility; <--- important
private:
void copy(const InterVehicleMessage& other);
protected:
bool operator==(const InterVehicleMessage&);
public:
//stuff
virtual veins::TraCIMobility& getMobility(); <--- important
virtual const veins::TraCIMobility& getMobility() const {return const_cast<InterVehicleMessage*>(this)->getMobility();} <--- important
virtual void setMobility(const veins::TraCIMobility& vehicle_mobility); <--- important
};
This all looks fine and dandy, I assume it functions as intended aswell.
But then when I try to make define the setMobility class I run into some problems.
void InterVehicleMessage::SetMobility(const veins::TraCIMobility& vehicle_mobility)
{
this->vehicle_mobility = vehicle_mobility;
}
This results in the error:
InterVehicleMessage_m.cc:240:28: error: object of type 'veins::TraCIMobility' cannot be assigned because its copy assignment operator is implicitly deleted
I'm not familiar with C++ enough to really know what this means. Is there anyone who could hint me into the right direction?
pastebin to TraCIMobility.h: https://pastebin.com/pGZEepxX
I've decided to save the information necesarry from TraCIMobility in individual variables.
So:
double speed;
veins::Coord position;
veins::Heading direction;
veins::Coord nextPositions[7];
Instead of:
veins::TraCIMobility vehicle_mobility;
As #PaulSanders stated in the comment, this class is not supposed to be copied.
Thanks everyone for their time and effort. Have a nice day.

C++ initialize list assignment in copy constructor and crashing in copy constructor

I have a situation where I am having trouble redefining a value that was defined in the initialization list. I'd like to redefine this in the copy constructor. I will throw down some sample code. I am also having an issue where my program is crashing once it gets into the for loop of my copy constructor. See anything wild going on there? Doesn't seem to make it out of the for loop without crashing.
in the header file:
class Calculator : public Tool {
private:
int numberKeys;
Tool** tools;
public:
Calculator();
Calculator(const Calculator& obj);
in the CPP file:
Calculator::Calculator()
:Tool("MyCalculator"),
numberKeys(0),
tools(nullptr)
{
}
Calculator::Calculator(const Calculator& obj )
{
numberKeys=obj.numberKeys;
tools = new Tool*[numberKeys];
*****How do I define :Tool("MyCalculator"),
*****to :Tool("YourCalculator"),
for (int x = 0; x < numberKeys; x++){
this->tools[x] = (obj.tools[i]->clone());
}
}
If I understand your question correctly, you want the default constructor and copy constructor for Calculator to pass different strings to the parent (base) class.
To do this, use the same assignment list format used for the default constructor. So the definition of the copy constructor will look like:
Calculator::Calculator(const Calculator& obj)
: Tool("YourCalculator"), numberKeys(obj.numberKeys) {
tools = new Tool*[numberKeys];
for (int i = 0; i < numberKeys; i++) tools[i] = obj.tools[i]->clone();
}
An extra few coding tips:
When delcaring member variables, I would use m_ or _ prefixes to destinguish from local variables. This way you don't have to keep using this, which can speed up coding in the long run.
Keep an eye on what temp veriables you use in your for loops - you declared int x = 0, and then used obj.tools[i] when i doesn't exist in the local scope.
You can comment code using //, or surround a comment block with /* comment */. ***** will not comment out code.
I would refrain from initializing member variables to nullptr if possible. This may get confusing later on when trying to manipulate them, as it may cause a null-pointer error.

C++ STL vector with odd size, 0 capacity before anything is added

I am debugging an issue where there is a seg fault when trying to call push_back to a vector. The seg fault is on the first attempt to add anything to the vector. For debug purposes, I printed out capacity and size before this first attempt, and the result is size: 529486, and capacity: 0.
The frustrating part is that this is an add-on vector, following the same formula used to work with other vectors, and those work. The size and capacity behave as expected with these other vectors.
As rough pseudo-code for what I am doing:
class NEWTYPE{
public:
Object* objPtr;
NEWTYPE();
void update(float );
void setObject(Object* o);
};
class ABCD{
std::vector<TYPE1*> type1List;
std::vector<TYPE2*> type2List;
std::vector<TYPE3*> type3List;
std::vector<TYPE4*> type4List;
std::vector<TYPE5*> type5List; // <== there were 5 other vectors working
std::vector<NEWTYPE*> NEWTYPEList;
}
void ABCD::addType1(TYPE1* n){
cout << type1List.size() << type1List.capacity; // <== as expected
type1List.push_back(n); // <== Works for each old type
}
void ABCD::addNewType(NEWTYPE* n){
cout << NEWTYPEList.size() << NEWTYPEList.capacity; // size: 529486, capacity:0 before first call
NEWTYPEList.push_back(n); // <== seg fault
}
ABCD instance;
// foo() : This procedure works correctly for the other vectors
void foo(){
NEWTYPE* test;
test = new NEWTYPE();
instance.addNewType(test);
}
I am not quite at a point to try to extract things to reproduce in a simple test case. That is one of my next steps.
Anyway, if anyone can point me in the right direction on this, I appreciate the advice. Thanks!
In my case, this turned out to be a build-related issue.
I updated the "master class" (ABCD in the pseudocode) to add the new vector. However, the file that declared the instance was not being rebuilt. The push_back function call was called for a vector that did not exist.
FYI...sorry for not being clear on my original question. Since I was using the same procedures as working parts of the code, my line of thinking was that I may have violated some stack constraint, or exceeded some default setting for vector related to how many vectors were being used.
Garbage returned by std::vector::capacity() and std::vector::size() most probably point to an uninitialized object. As object in your example is global I suspect function foo called from another global object constructor. As order of initialization of global objects is not defined you can have different behavior with different instances of vectors. Possible solution - use singleton object with a local static object:
ABCD &getInstance()
{
static ABCD theInstance;
return theInstance;
}
this way theInstance will be initialized when function getInstance() is called first time. This method does not solve issue with destructor order though, you should design your program the way that destrutcors of global objects should not call methods of other global objects, or use different singleton type (for example phoenix).

QVector<T> operator= and operator[]

I'm writing a program for my friends during my summer time and I occurred really strange problem.
I'm assigning a QVector< T > to other QVector< T > with operator= in my homemade template class and then trying to check whethere this 2nd QVector< T > have any elements. First, I'm checking it's size and it's good, but when I use operator[] and function GetName() which is a member of class T.
Here's some code:
template <template T> class Turniej {
private:
QVector<T>* list_;
QVector<Stol<T> > stoly_;
int round_;
int max_rounds_;
Turniej() {round_=1;}
public:
static Turniej& GetTurniej() {
static Turniej turniej;
return turniej; }
void SetList(QVector<T> *list) {list_=list; }
QVector<T>& GetList() {return *list_;}
//Some other irrelevant methods
};
Then I invoke SetList() function with reference to QVector filled with 2 objects of Gracz class
Turniej<Gracz>::GetTurniej().SetList(&list)
And when I'm finally trying to get to the list_ object in Turniej class by code below, I get this error:
ASSERT failure in QVector::operator[]: "index out of range", file .../QtCore/qvector.h, line 356
qDebug()<<Turniej<Gracz>::GetTurniej().GetList()[0].GetName();
Where GetName() returns some QString and for certain that method exists in Gracz class.
I would really appreciate any help, because I'm stuck with it for 2 days and have completely no idea what's going on. What is strange, I was trying to google that error but I haven't found any topic with error in that particular line of qvector.h.
I'm using Qt 5.0.2 with Qt Creator
Thanks for any help!
when you call SetList, you are transferring the ownership of the list, are you shure you are not deleting it (or it is not getting deleted automatically) afterwards?
Change list_=list; to list_ = new QVector(list). Maybe your vector is modified somewhere outside of your class? You're just keeping reference to vector given to your method, it seems like copying is what you want.
updated
I see your class is a singleton. Always remember to think twice before making a class a singleton - it's not a thing you want to have in your code, and it should be avoided when possible.

Debug assertion failed - Vector iterator not dereferencable

I have got this Runtime Error when running this code:
void AlienShipManager::Update(float timeDelta,
BulletManager* bulletManager,
ParticleManager* particleManager,
GameStringSystem* stringBatch)
{
unsigned int i = 0;
while (i < m_alienShipList.size())
{
AlienResult result = m_alienShipList[i].Update(timeDelta, bulletManager);
switch (result)
{
case AlienResult::Dead:
break;
default:
break;
}
++i
}
}
in line
AlienResult result = m_alienShipList[i].Update(timeDelta, bulletManager);
There is how I add AlienShip to vector class:
m_alienShipList.push_back(AlienShip(position, speed, m_screeSize, m_alienShipTexture));
error also appers if I chance that to:
AlienShip* newAlien = new AlienShip(position, speed, m_screeSize, m_alienShipTexture);
m_alienShipList.push_back(*newAlien);
delete newAlien;
but does not appear if I change that to:
AlienShip* newAlien = new AlienShip(position, speed, m_screeSize, m_alienShipTexture);
m_alienShipList.push_back(*newAlien);
which hence lead to huge memory leaks.
This is how looks my AlienShip class:
#pragma once
#include "Body.h"
#include "BulletManager.h"
#include "ParticleManager.h"
enum AliensShipState
{
flying,
dying,
dead,
escaped
};
enum AlienResult
{
No,
Hit,
Dying,
Dead,
Escaped
};
class AlienShip : public Body
{
public:
AlienShip(void);
AlienShip(float2& position, float2& speed, float2* screenSize, ID3D11Texture2D* alienTexture);
~AlienShip(void);
AlienResult Update(float timeDelta, BulletManager* bulletManager);
void Draw(BasicSprites::SpriteBatch^ spriteBatch);
protected:
float m_baseY;
AliensShipState m_state;
float2* m_screenSize;
};
AlienShip class is inherited from Body class, which has Sprite class inside it, which has another vector inside it.
But since Sprite class is working perfectly elsewhere, I don't think it is source of error.
I wonder why this happens, because I can't find the relationship between deleting temporary object and corrupting vector iterator, If it corrupted at all.
Also program compiles and runs in Release, but with some data corruption.
I am using Visual Studio 2012 Beta for Windows 8.
Please write if you need more source code.
Unfortunately it is very hard to post all code, as this is complex program.
Given that it doesn't work when you add the item to the vector by value but it does when you leak a pointer, I have 95% confidence that your copy constructor for AlienShip does a shallow copy, causing your problems.
EDIT: Note that m_alienShipList.push_back(AlienShip(position, speed, m_screeSize, m_alienShipTexture)); causes a copy of your class and if the copy constructor doesn't work right it will cause problems later.
In fact if the AlienShip definition you've pasted is correct there is in fact only the default copy constructor which likely does the wrong thing (further reinforced by the fact that you have your own destructor).
Either implement a copy constructor that does a deep copy, or more preferably rewrite your class to use RAII to manage the memory for you so that the default copy is correct.