I'm debugging a program where I found some data being changed where they shouldn't. I traced the program using gdb and I found the target data is changed in a delete function of some other data!
At first I figured there was some memory overlapping between both areas, but then I checked the start and end addresses of both areas and they do not overlap! that only leaves the delete line!
this is the function where this happens, the data that shouldn't change is freemap and the data being freed is synthops:
void BasicBlock::free() {
cout << "freemap 2 : " << this->mfnlo_loc.chunk->freemap[2] << "\n";
cout << "freemap 59 : " << this->mfnlo_loc.chunk->freemap[59] << "\n";
cout << "freemap : " << &(this->mfnlo_loc.chunk->freemap) << "\t" << sizeof(this->mfnlo_loc.chunk->freemap)+&(this->mfnlo_loc.chunk->freemap) << "\n";
cout << "synthops : " << synthops << "\t" << synthops+sizeof(uopimpl_func_t)*count << "\n";
if (synthops)
{
delete[] synthops;
}
cout << "freemap 2 : " << (this->mfnlo_loc.chunk->freemap[2]) << "\n";
cout << "freemap 59 : " << this->mfnlo_loc.chunk->freemap[59] << "\n";
synthops = NULL;
::free(this);
}
the output is like this:
freemap 2 : 1
freemap 59 : 1
freemap : 0x3319a50 0x3319a90
synthops : 0x3319d50 0x331acd0
freemap 2 : 0
freemap 59 : 0
It is shown that freemap changes after the delete line, It also shows that they both don't overlap in memory.
synthops is allocated in another function like this:
bb.synthops = new uopimpl_func_t[bb.count];
why does this happen? the code is a mix of C and C++ which means there is a mix of new and malloc (but used consistently, no delete with malloc for example). is that the reason for this? or is it something else?
My psychic debugging skills tell me that you didn't follow the rule of three for BasicBlock, specifically you omitted the copy constructor. Then you (shallow) copied that object (and specifically the synthops member), and that then resulted in double deletion at which point all bets are off.
Related
I do not know what to put in the 'Title' box so I consider that the title does not completely answer my problem and I am sorry about it.
First of all, I would like to give a bit of context. I discovered the development of the network for two weeks now for a 3D game.
Today I'm focusing on shipping packages using std::vector to send templates as .obj, but that's not my problem.
The problem is that I am not receiving the information from this vector.
As a picture is worth a thousand words, here is my code (this code is just to test the encryption of the data in a char[] on the 'server' side and the reception on the client side).
My C++ program:
#include <vector>
#include <iostream>
int main()
{
/* -- server -- */
// variables to buffer
std::vector<int> vec = { 1, 25, 156, 0, 1 };
short type = 25;
int written = 0;
char buffer[256] = {};
memcpy(&buffer[written], &type, sizeof(type));
written += sizeof(type);
memcpy(&buffer[written], &vec, sizeof(vec));
written += sizeof(vec);
std::cout << "/* -- Server -- */\n" << std::endl;
std::cout << "[written] --> " << "Size : " << sizeof(written) << " | Value : " << written << std::endl;
std::cout << "[type] --> " << "Size : " << sizeof(type) << " | Value : " << type << std::endl;
std::cout << "[vec] --> " << "Size : " << sizeof(vec) << " | Value : " << vec.data() << std::endl;
// 'send' to client && 'receive' from server \\ (for example)
char buffer2[256] = {};
memcpy(&buffer2, &buffer[0], sizeof(buffer2));
/* -- client -- */
// buffer to variables
std::vector<int>* vec2;
short type2 = 0;
int read = 0;
memcpy(&type2, &buffer[read], sizeof(type2));
read += sizeof(type2);
memcpy(&vec2, &buffer[read], sizeof(vec2));
read += sizeof(vec2);
std::cout << "\n\n";
std::cout << "/* -- Client -- */\n" << std::endl;
std::cout << "[read] --> " << "Size : " << sizeof(read) << " | Value : " << read << std::endl;
std::cout << "[type2] --> " << "Size : " << sizeof(type2) << " | Value : " << type2 << std::endl;
std::cout << "[vec2] --> " << "Size : " << sizeof(vec2) << " | Value : " << vec2->data() << std::endl;
std::cout << "\n"; system("pause");
return 0;
}
Return of the cmd:
/* -- Server -- */
[written] --> Size : 4 | Value : 18
[type] --> Size : 2 | Value : 25
[vec] --> Size : 16 | Value : 00589A00
/* -- Client -- */
[read] --> Size : 4 | Value : 6
[type2] --> Size : 2 | Value : 25
[vec2] --> Size : 4 | Value : 00000000
Press any key to continue...
memcpy(&buffer[written], &vec, sizeof(vec));
You already have problems here, even before receiving anything.
sizeof(vec) is the size of std::vector<int>. Which will probably be 8 or 16 bytes, or something like this. The size of the vector will always be the same, whether the vector is empty, or holds an image of every page in an encyclopedia.
A vector, and what's in a vector, are two completely different things.
A vector's size() method gives the number of values in the vector, so the above should obviously be:
memcpy(&buffer[written], vec.data(), vec.size()*sizeof(int));
The rest of the code should be adjusted accordingly.
Similarly, the process of deserializing into a vector is also wrong, in the shown code:
std::vector<int>* vec2;
This is a pointer to a vector. In C++, before using a pointer it must be initialized to point to an existing instance of the same type. There's nothing in the shown code that does that.
memcpy(&vec2, &buffer[read], sizeof(vec2));
Since vec2 is a pointer, sizeof(vec2) will be the size of a pointer: either 4 or 8 bytes. This attempts to deserialize the raw memory address of a pointer. Again, this makes no sense.
What the shown code is attempting to do should be:
Declare your vector
std::vector<int> vec2;
Determine how many values will be read into the vector, and resize it. If, for example, you know that you have n bytes worth of raw integer data to deserialize:
vec2.resize(n / sizeof(int));
At this point you can copy the raw data into th epointer.
memcpy(vec2.data(), &buffer[written], n);
This approach is slightly inefficient, due to resizing, but that's a secondary issue. It's also possible to implement this logic in more C++-friendly ways, but that's also a secondary issue. The main issue is that your sizeof will not magically give you the number of bytes that will be read into a vector. This is something that you need to track by yourself. There's very little that C++ will do for you, you'll always have to do all the work. You need to figure out how to keep track of the actual number of bytes that were read, that comprise the contents of the vector, then resize and read into the vector, accordingly.
Some time ago I used Visual Studio, and there was a function _msize for counting size of dynamic array.
Now I'm trying to do the same in Xcode. I've read somewhere, that for that purpose in Xcode I have to use malloc_size function, but it returns something strange.
char* mass = new char[6]{"HELLO"};
cout << "malloc_size(mass) " << malloc_size(mass)<<endl;
cout << "sizeof(mass) " << sizeof(mass)<<endl;
cout << "sizeof(mass[0]) " << sizeof(mass[0])<<endl;
cout << "malloc_size(mass)/sizeof(mass) " << malloc_size(mass)/sizeof(mass)<< endl;
Output:
malloc_size(mass) 16
sizeof(mass) 8
sizeof(mass[0]) 1
malloc_size(mass)/sizeof(mass) 2
Could anybody suggest something what behaves similar to _msize?
I have 2 QCheckbox tables, each contains 11 elements.
I declare them as following in my class :
QCheckBox *sectionTable[10];
QCheckBox *postTable[10];
For each QCheckBox, I do this
QCheckBox* checkboxA = new QCheckBox("A");
sectionTable[0] = checkboxA;
Through my test method, I would like to return the content of each element of my QCheckbox tables.
To do so, I've done this test :
/** TEST() **/
void VGCCC::test()
{
sectionTable[0]->setText("A");
sectionTable[1]->setText("B");
sectionTable[2]->setText("C");
sectionTable[3]->setText("D");
postTable[0]->setText("E");
postTable[1]->setText("F");
postTable[2]->setText("G");
postTable[3]->setText("H");
int i=0;
do
{
m_testTextEdit->insertPlainText(sectionTable[i]->text());
std::cout << "SECTION TABLE " << sectionTable[i]->text().toStdString() << "\n" << std::endl;
i++;
}
while(!sectionTable[i]->text().isNull());
do
{
m_testTextEdit->insertPlainText(postTable[i]->text());
std::cout << "POST TABLE " << postTable[i]->text().toStdString() << "\n" << std::endl;
i++;
}
while(!postTable[i]->text().isEmpty());
}
My application is compiling, and also running. But when I call the test function, my application crash.
How can we explain this problem ?
I would like to notify that I get a result in my console. It seems my test is half working, but is crashing at the end of the 1st do/while loop, when I get out of my condition.
With regard to the 11 elements: QCheckBox *sectionTable[10]; defines only 10 slots (0 through 9) for elements.
int i=0;
do
{
m_testTextEdit->insertPlainText(sectionTable[i]->text());
std::cout << "SECTION TABLE " << sectionTable[i]->text().toStdString() << "\n" << std::endl;
i++;
}
while(!sectionTable[i]->text().isNull());
Has the potential to reach past ten or eleven elements. Unless the terminating condition is found earlier, there is nothing to stop sectionTable[i] from trying to read sectionTable[11] to call its text method. If it manages to survive the call to the out-of-range sectionTable[11]->text(), it will then try calling sectionTable[11]->text().isNull(). Possibly this will be survivable as well and not be NULL. In this case sectionTable[12] will be tested. This will continue until the program hits really bad memory and crashes, a null is found, or pigs become the terror of the airways we all know they truly wish to be.
Note that i is not set back to 0 after this loop, so the first postTable to be inspected in the next loop will be at the same index as the last sectionTable.
So if sectionTable[5]->text().isNull() was NULL, postTable[5] will be the first postTable indexed and inspected.
do
{
m_testTextEdit->insertPlainText(postTable[i]->text());
std::cout << "POST TABLE " << postTable[i]->text().toStdString() << "\n" << std::endl;
i++;
}
while(!postTable[i]->text().isEmpty());
This loop has the same error in the exit condition as the sectionTable loop.
I find out how to solve the problem. As said in the answer before (#user4581301), I didn't set back my iterator i to 0.
Also, to avoid the "out of range" crash, I put a second condition which is i<sizeof(sectionTable[i]);
This is my fonctional test function :
/** TEST() **/
void VGCCC::test()
{
int i = 0;
do
{
m_testTextEdit->insertPlainText(sectionTable[i]->text());
std::cout << "SECTION TABLE " << m_materialMap[sectionTable[i]].c_str() << "\n" << std::endl;
i++;
}
while(!sectionTable[i]->text().isNull() && i<sizeof(sectionTable[i]));
i = 0;
do
{
m_testTextEdit->insertPlainText(postTable[i]->text());
std::cout << "POST TABLE " << postTable[i]->text().toStdString() << "\n" << std::endl;
std::cout << "POST TABLE " << m_materialMap[postTable[i]].c_str() << "\n" << std::endl;
i++;
}
while(!postTable[i]->text().isEmpty() && i<sizeof(postTable[i]));
}
There is some problem during the run time of my program and i am unable to get what the problem is.
what happens basically is , my program automatically closes and displays the following in Microsoft visual c++ 2010 express window
What could be the reasons for this ? I have no idea why this is happening.
Let me tell that in my program i have used pointers too often and have used character arrays which i write to the disc
The program is too large to display
This is the function called after which my program stops :
void display_databases()
{
struct info_of_trains
{
int train_no;
char train_name[25];
char boarding_pt[25];
char destination[25];
int first_seats;
int fare_first;
int second_seats;
int fare_second;
char date[20];
};
info_of_trains e;
cout<<"TRno. TRname B.pt D.pt F.seats F.fare S.seats F.second Date\n";
FILE *fp;
fp=fopen("database","r");
if(fp==NULL)
{
cout<<"failure";
}
else
{
while(fread(&e,sizeof(e),1,fp)==1)
{
printf(e.train_no,e.train_name,e.boarding_pt,e.destination,e.first_seats,e.fare_first,e.second_seats,e.fare_second,e.date);
cout<<"-------------------------------------------------------------------------------\n";
}
fclose(fp);
}
}
This is where execution stops :!
You seem to have hit a breakpoint, or your program had an access violation (reading an illegal pointer). You also seem to have maximized/detached the debugging panels. You can reattach the panel by dragging the yellow bar at the top to the lower part of the screen.
Did you recieve a warning message before it happened? Otherwise, did you define a breakpoint (clicking in the left margin of the code editor, so a red circle appears there)
EDIT: As pointed out in the comments, the error occurs because you use printf the wrong way. Use cout instead, as you did above:
cout << e.train_no <<" " << e.train_name << " " << e.boarding_pt << " " << e.destination << " " << e.first_seats << " " << e.fare_first << " " << e.second_seats << " " << e.fare_second << " " << e.date << endl;
I have a vector of UnderlyingClass pointers stored in another object, and inside a method in UnderlyingClass I want to add the "this" pointer to the end of that vector. When I look at the contents of the vector immediately after the push_back call, the wrong pointer is in there. What could be going wrong?
cout << "this: " << this << endl;
aTextBox.callbacks.push_back(this);
cout << "size is " << aTextBox.callbacks.size() << endl;
cout << "size-1: " << aTextBox.callbacks[aTextBox.callbacks.size()-1] << endl;
cout << "back: " << aTextBox.callbacks.back() << endl;
cout << "0: " << aTextBox.callbacks[0] << endl;
cout << "this: " << this << endl;
cout << "text box ptr: " << &aTextBox << endl;
cout << "text box callbacks ptr: " << &(aTextBox.callbacks) << endl;
Here's the output:
this: 0x11038f70
size is 1
size-1: 0x11038fa8
back: 0x11038fa8
0: 0x11038fa8
this: 0x11038f70
text box ptr: 0x11039070
text box callbacks ptr: 0x11039098
By the way, callbacks is a vector of WebCallback pointers, and UnderlyingClass implements WebCallback:
std::vector<WebCallback*> callbacks;
class UnderlyingClass
:public WebCallback
Copied from comments: (see Answer below)
output:
this: 0x6359f70
size is 1
size-1: 0x6359fa8
back: 0x6359fa8
0: 0x6359fa8
this: 0x6359f70
WebCallback This: 0x6359fa8
text box ptr: 0x635a070
text box callbacks ptr: 0x635a098
okay, so that explains why the pointers don't match up.
My real question, then, is this:
how do I get the correct version of a method to be called? Specifically, WebCallback stipulates that a function onWebCommand() be implemented, and right now callbacks[0]->onWebCommand() is not causing the onWebCommand() that I wrote in UnderlyingClass to be executed.
This can happen with multiple inheritance, if your layout looks like this:
class UnderlyingBase {
char d[56];
};
class UnderlyingClass
:public UnderlyingBase,
public WebCallback {
};
Then the layout can be like this, for each object involved. The last one is the complete object containing the first two ones as base-class sub-objects, and that you take the pointer of, and which will be converted to WebCallback*.
[UnderlyingBase]
> char[56]: 56 bytes, offset 0x0
[WebCallback]
> unknown: x bytes, offset 0x0
[UnderlyingClass]
> [UnderlyingBase]: 56 bytes (0x38 hex), offset 0x0
> [WebCallback]: x bytes, offset 0x38
Now since your vector contains WebCallback*, the compiler adjusts the pointer to point to the WebCallback sub-object, while when it would point to UnderlyingClass or UnderlyingBase, it would start 0x38 (56) bytes earlier.
Add this to your print out:
cout << "this: " << this << endl;
cout << "WebCallback This: " << dynamic_cast<WebCallback*>(this) << endl;
I bet this is what you are looking for.