Double vector hides variables - c++

I'm having an interesting problem when I'm accessing a double vector. The idea is that I have deleted all information prior to accessing the vector. A for loop tries to access the vector and successful says that the vector is empty, but when I access the vector point directly it shows that there are variables still in the vector.
Also, the vector was set up like so:
vector<vector<string>> proTable;
Here is the loop attempting to access the vector.
for(int a = 0; a < proTable.size(); a++)
{
for(int b = 0; b < proTable[a].size(); b++)
{
cout << proTable[a][b] << "\t";
}
}
But if I edit the for loop this way it returns the variable inside.
for(int a = 0; a < proTable.size(); a++)
{
for(int b = 0; b < proTable[a].size(); b++)
{
cout << proTable[a][b] << "\t";
}
cout << proTable[0][0];
}
The first prints nothing out. The second prints X which was in the vector before. Also, the vector does not show that it is empty.
This is how I was deleting it if it matters.
void MRelation::RemoveColumn(vector<int> rem)
{
while(!rem.empty())
{
int z = rem[rem.size() - 1];
for(int a = 0; a < proTable.size(); a++)
{
for(int b = z; b < proTable[a].size() - 1; b++)
{
proTable[a][b] = proTable[a][b+1];
}
proTable[a].pop_back();
}
rem.pop_back();
}
}
The vector rem holds the columns that need to be deleted from the table.

I have deleted all information prior to accessing the vector.
Accessing an vector out of bounds has undefined behaviour. Since your vector is empty, proTable[0] is out of bounds. In the line cout << proTable[0][0];, you access proTable[0]. Therefore the behaviour of your program is undefined.
it shows that there are variables still in the vector.
You cannot jump to such conclusion from observing undefined behaviour.
"There are variables still in the vector" was not necessarily the reason why you saw output. You saw output because the behaviour was undefined.

I found out what it was. I you delete the contents of the inner vector but don't delete the vectors themselves then the vector will think that it contains something still and will pull out information that doesn't exist anymore. here is the code I was have problems with. It has been edited with an if statement to correct it.
void MRelation::FinalPrint()
{
if(curTable.size() < 2)
{
ss << "? No\n";
}
else
{
ss << "? Yes(" << curTable.size() - 1 << ")\n";
}
if(!proTable[0].empty()) //This was added in after to correct the problem
{
for(int c = 1; c < proTable.size(); c++)
{
ss << " " << proTable[0][0] << "=" << proTable[c][0];
for(int d = 1; d < proTable[0].size(); d++)
{
ss << ", ";
ss << proTable[0][d] << "=" << proTable[c][d];
}
ss << "\n";
}
}
}
Sorry about not putting everything in context before. I was trying to put in as much relavant information without putting in 300 lines of code.

Related

Passing the elements of a vector to a different data structure by address

I am building a 2d game and I am storing all my enemy objects in an array. Right now I am trying to implement a quadtree. Currently I am just trying to build the quadtree and am not concerned with collisions. The code that pushes items to the quadtree is the following :
for (std::vector<Enemy>::iterator i=m_enemies.begin(); i != m_enemies.end(); ++i) {
std::cout << &(*i) << "Address of the object" << std::endl;
m_quad.Insert(&(*i));
}
The code for the Insert is the following :
void Quad::Insert(sf::RectangleShape* l_gameObject){
std::cout << &l_gameObject << "dsa1" << std::endl;
std::cout << "called insert " << m_objects.size() << std::endl;
m_objects.push_back(l_gameObject);
if (m_level < m_maxLevel) {
if (m_objects.size() > 3) {
std::cout<< "creating subregions " << m_objects.size() << std::endl;
m_subRegions.push_back(Quad(m_x,m_y,m_width/2.f, m_height/2, m_level + 1, m_maxLevel-1));
m_subRegions.push_back(Quad(m_x+m_width/2.f,m_y,m_width/2.f,m_height/2.f, m_level + 1, m_maxLevel-1));
m_subRegions.push_back(Quad(m_x+m_width/2.f, m_y + m_height/2.f, m_width/2.f, m_height/2.f, m_level + 1, m_maxLevel-1));
m_subRegions.push_back(Quad(m_x, m_y + m_height/2.f, m_width/2.f, m_height/2.f, m_level + 1, m_maxLevel-1));
std::vector<int> temp;
for (int i=0; i < m_objects.size(); i++){
for (int j=0; j< m_subRegions.size(); j++) {
if (m_subRegions[j].Contains(m_objects[i])) {
m_subRegions[j].Insert(m_objects[i]);
temp.push_back(i);
break;
}
}
}
for (int i = temp.size(); i > -1; i--){
m_objects.erase(m_objects.begin() + temp[i]);
}
}
}
}
When I print the address that I am passing to the Insert function and the one I have in the function I see that they are different. In fact the on in is always the same and the one I pass is always different as it should be. Could anyone clarify why that is the case ?
EDIT : Thanks to gsamaras for pointing out that I was printing the address of the parameter.
Followup question
When I use the methods of the object I am addressing in the first for loop I get the correct results, but when I do the same thing in the Insert function I get 0. Why is that ?
You are printing the address of the address.
Change this:
std::cout << &l_gameObject << "dsa1" << std::endl;
to this:
std::cout << l_gameObject << "dsa1" << std::endl;
in order to print the same thing as outside your of your function.
Inside Insert, you're printing the address of the parameter.
Outside Insert, you're printing the parameter's value.
You want
std::cout << l_gameObject << "dsa1" << std::endl;
since l_gameObject is the address you're passing in.

Finding this strange bug? It crashes without noticing anything

I wrote a function within my code that should create some sort of matrices. It is fine when the size is small, but when it gets bigger, it crashes at the middle of this function without giving any information. I did that with both debug and release mode and same thing happened. Any idea on what can be wrong? Someone suggested me it could be buffer overrun.
In this function when kl.mechelms get bigger than a certain number, it crashes. The following code uses a function and gets a 3 by 3 matrix and stores it in kl.scoff which size is [3][3][kl.mechelms][kl.mechelms]. The problem happens when kl.mechelms are like bigger than 7000, but we need far more than that for our code.
Could the function Calc_3D which I use within this part cause the problem? I think it shouldn't since it just reads some values.
for (int z = 0;z<3;z++) {
for (int q = 0;q<3;q++) {
kl.scofsarr[z][q] = new double *[kl.mechelms];
}
}
for (int i = 0;i<kl.mechelms;i++) {
cout << "element " << i << "of " << kl.mechelms << endl;
kl.comments << "element " << i << "of " << kl.mechelms << endl;
for (int z = 0;z<3;z++) {
for (int q = 0;q<3;q++) {
kl.scofsarr[z][q][i] = new double[kl.mechelms];
}
}
for (int j = 0;j<kl.mechelms;j++) {
Calc_3D(i,j, kl.elmx[j], kl.elmy[j], kl.elmz[j], kl.anglemat[j], kl.dip[j], kl.elmx[i],kl.elmy[i],kl.elmz[i],
kl.elma[i],kl.rectza,kl.anglemat[i],kl.dip[i], kl.G, kl.v, kl.scofs, kl.rdepth);
for (int z = 0;z<3;z++) {
for (int q = 0;q<3;q++) {
kl.scofsarr[z][q][i][j] = kl.scofs[z][q];
}
}
}
}

Why does the following element appear at both the head and tail of this c++ vector after a call to erase and push_back?

I'm trying to understand why the following code behaves the way it does:
std::vector<int*> k;
for (int i = 0; i < 5; ++i) k.push_back(new int(i));
for (int i = 0; i < k.size(); ++i)
std::cout << "k[" << i << "]: " << *k[i] << "#" << k[i] << ", ";
std::cout << std::endl;
for (int i = 0; i < k.size(); ++i) {
int* p = k[i];
delete p;
if (i >= 2) {
k.erase(k.begin(), k.begin() + i);
k.push_back(new int(5));
break;
}
}
for (int i = 0; i < k.size(); ++i)
std::cout << "k[" << i << "]: " << *k[i] << "#" << k[i] << ", ";
std::cout << std::endl;
When I run this, the first time we print the contents of k I see this:
[0]: 0#0x1774e010, k[1] 1#0x1774e050, k[2]: 2#0x1774e030, k[3]: 3#0x1774e070, k[4]: 4#0x1774e0c0
This is what I expected. Then after the erase and the push i would expect the first two elements to be gone, the last three to be shifted, and the 5th one to appear at the end. However, i get this instead:
k[0]: 5#0x1774e030, k[1]: 3#0x1774e070, k[2]: 4#0x1774e0c0, k[5]: 5#0x1774e030,
I do see k[5] appearing at the end after the rest of the elements shifted but I am not understanding why it also appears as the first element too.
The second argument to vector::erase is a one past the end iterator. This is the typical form for iterator ranges in the standard C++ library.
So, when i == 2 the statement k.erase(k.begin(), k.begin() + i) only erases the first two elements, leaving the one you just deleted still in the vector. This goes on to cause bogus results when you try to use the deleted pointer.
(Technically it is undefined behaviour to do the erase also, since it involves reading the deleted pointer).
Possibly, the reason you see k[0]: 5#0x1774e030 instead of random garbage would be that your new int reallocates into the same space you just delete ; and I guess k[5]: on that line is a typo for k[3]: .

C++ Skipping elements in a one d array

I have an assignment with several ways to manipulate an array, but I'm having trouble with one of the parts.
I am reading about 50 numbers into the array from a .txt file
And for every odd location in the array (1,3,5,…), I have to subtract it from the previous even location (0,2,4,…) and store results in the odd location. Then I print out all values in the array.
Here is what I have so far:
void oddMinusEven(int ary[],int num)
{
for(int idx = ary[0]; idx<num; ary[idx+2])
{
ary[idx] = ary[idx+2]-ary[idx];
cout<<ary[idx]<<endl;
}
}
How do I do this? If you could provide some examples, that would be great.
This should do:
void oddMinusEven(int ary[], int num) {
for(int i = 1; i < num; i += 2) {
ary[i] = ary[i-1] - ary[i];
std::cout << "a[" << i << "] = " << ary[i] << std::endl;
}
}

Converting and Passing Arrays

I basically want to pass this array of data I'm reading to diffent functions and eventually plot it.
The array contains a 32 bit word of '1's and '0's, I then want to add these individual bits together to see where my data spikes. So in other words if I add "0100" to "0110" I get "0210" - which is probably easier done with separate bins and plotting.
At the moment I'm just getting garbage out.
void binary(int convert, int* dat) {
bitset<32> bits(convert);
//cout << bits.to_string() << endl;
char data[32];
for(unsigned i = 0; i < 32; ++i) {
data[i] = bits[i];
}
for(unsigned i = 32; i; --i) {
dat[i] = (int(data[i-1]))+dat[i];
}
}
void SerDi() {
int dat[32];
cout << " Reading data from memory..." << endl;
ValVector< uint32_t> data=hw.getNode("SerDi.RAM").readBlock(8);
hw.dispatch();
cout << data[0]<<endl;
cout << data[1]<<endl;
for (unsigned i = 2; i < 7; i++) {
binary(data[i], dat);
}
cout << dat[7] << endl;
graph(dat); //passes the array to a place where I can plot the graph
}
You have
int dat[32];
But in convert you have i = 32 and dat[i] That will access something outside of the array and bad things will happen.
Also that is not initialized. Add a memset/loop somewhere to make dat initially 0.