Delete an object from a vector - c++

Step 1. Create an instance of a class
Step 2. Push this instance to a vector
Step 3. Call delete this; in a member method of an instance
Step 4. Everything is Ok
Step 5. Push something to the vector and get this
*** glibc detected *** ./app: double free or corruption (fasttop): 0x0000000001017930 ***
======= Backtrace: =========
/lib/libc.so.6(+0x71bd6)[0x7f607d60cbd6]
/lib/libc.so.6(cfree+0x6c)[0x7f607d61194c]
./app[0x40231c]
./app[0x402290]
./app[0x4053c0]
./app[0x4048fe]
./app[0x404246]
./app[0x403fe0]
./app[0x402400]
./app[0x4035cb]
./app[0x4034d3]
/lib/libpthread.so.0(+0x68ca)[0x7f607e2b78ca]
/lib/libc.so.6(clone+0x6d)[0x7f607d66a92d]
======= Memory map: ========
00400000-0040f000 r-xp 00000000 09:03 60427370 /root/AHS/app
0060e000-0060f000 rw-p 0000e000 09:03 60427370 /root/AHS/app
01017000-01038000 rw-p 00000000 00:00 0 [heap]
7f6074000000-7f6074021000 rw-p 00000000 00:00 0
7f6074021000-7f6078000000 ---p 00000000 00:00 0
7f607a595000-7f607a596000 ---p 00000000 00:00 0
7f607a596000-7f607ad96000 rw-p 00000000 00:00 0
7f607ad96000-7f607ad97000 ---p 00000000 00:00 0
7f607ad97000-7f607b597000 rw-p 00000000 00:00 0
7f607b597000-7f607b598000 ---p 00000000 00:00 0
7f607b598000-7f607bd98000 rw-p 00000000 00:00 0
7f607bd98000-7f607bd99000 ---p 00000000 00:00 0
7f607bd99000-7f607c599000 rw-p 00000000 00:00 0
7f607c599000-7f607c59a000 ---p 00000000 00:00 0
7f607c59a000-7f607cd9a000 rw-p 00000000 00:00 0
7f607cd9a000-7f607cd9b000 ---p 00000000 00:00 0
7f607cd9b000-7f607d59b000 rw-p 00000000 00:00 0
7f607d59b000-7f607d6f4000 r-xp 00000000 09:03 60425052 /lib/libc-2.11.3.so
7f607d6f4000-7f607d8f3000 ---p 00159000 09:03 60425052 /lib/libc-2.11.3.so
7f607d8f3000-7f607d8f7000 r--p 00158000 09:03 60425052 /lib/libc-2.11.3.so
7f607d8f7000-7f607d8f8000 rw-p 0015c000 09:03 60425052 /lib/libc-2.11.3.so
7f607d8f8000-7f607d8fd000 rw-p 00000000 00:00 0
7f607d8fd000-7f607d913000 r-xp 00000000 09:03 60425245 /lib/libgcc_s.so.1
7f607d913000-7f607db12000 ---p 00016000 09:03 60425245 /lib/libgcc_s.so.1
7f607db12000-7f607db13000 rw-p 00015000 09:03 60425245 /lib/libgcc_s.so.1
7f607db13000-7f607db93000 r-xp 00000000 09:03 60425438 /lib/libm-2.11.3.so
7f607db93000-7f607dd93000 ---p 00080000 09:03 60425438 /lib/libm-2.11.3.so
7f607dd93000-7f607dd94000 r--p 00080000 09:03 60425438 /lib/libm-2.11.3.so
7f607dd94000-7f607dd95000 rw-p 00081000 09:03 60425438 /lib/libm-2.11.3.so
7f607dd95000-7f607de8b000 r-xp 00000000 09:03 60032880 /usr/lib/libstdc++.so.6.0.13
7f607de8b000-7f607e08b000 ---p 000f6000 09:03 60032880 /usr/lib/libstdc++.so.6.0.13
7f607e08b000-7f607e092000 r--p 000f6000 09:03 60032880 /usr/lib/libstdc++.so.6.0.13
7f607e092000-7f607e094000 rw-p 000fd000 09:03 60032880 /usr/lib/libstdc++.so.6.0.13
7f607e094000-7f607e0a9000 rw-p 00000000 00:00 0
7f607e0a9000-7f607e0b0000 r-xp 00000000 09:03 60425177 /lib/librt-2.11.3.so
7f607e0b0000-7f607e2af000 ---p 00007000 09:03 60425177 /lib/librt-2.11.3.so
7f607e2af000-7f607e2b0000 r--p 00006000 09:03 60425177 /lib/librt-2.11.3.so
7f607e2b0000-7f607e2b1000 rw-p 00007000 09:03 60425177 /lib/librt-2.11.3.so
7f607e2b1000-7f607e2c8000 r-xp 00000000 09:03 60425205 /lib/libpthread-2.11.3.so
7f607e2c8000-7f607e4c7000 ---p 00017000 09:03 60425205 /lib/libpthread-2.11.3.so
7f607e4c7000-7f607e4c8000 r--p 00016000 09:03 60425205 /lib/libpthread-2.11.3.so
7f607e4c8000-7f607e4c9000 rw-p 00017000 09:03 60425205 /lib/libpthread-2.11.3.so
7f607e4c9000-7f607e4cd000 rw-p 00000000 00:00 0
7f607e4cd000-7f607e4eb000 r-xp 00000000 09:03 60425293 /lib/ld-2.11.3.so
7f607e6da000-7f607e6df000 rw-p 00000000 00:00 0
7f607e6e7000-7f607e6ea000 rw-p 00000000 00:00 0
7f607e6ea000-7f607e6eb000 r--p 0001d000 09:03 60425293 /lib/ld-2.11.3.so
7f607e6eb000-7f607e6ec000 rw-p 0001e000 09:03 60425293 /lib/ld-2.11.3.so
7f607e6ec000-7f607e6ed000 rw-p 00000000 00:00 0
7fff4ee3b000-7fff4ee50000 rw-p 00000000 00:00 0 [stack]
7fff4efff000-7fff4f000000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted
Could someone please tell me, what is this, why this occurs and how do I fix it?

It's because you freed memory you didn't own. The vector owns the memory containing its contents.
delete this; is like taking a rental car to the salvage yard when you're done with it. Don't do that, the rental company expects it back!
Be careful of the difference between owning memory, and merely having control of it loaned to you.

Doing delete this for an object belonging to a vector you are making two big mistakes:
it's the vector that manages the memory where that instance is stored (it allocates it, deallocates it, ...), so you shouldn't mess with it. In other words, since you don't own that memory you must leave it alone.
delete is a correct match if the object was allocated with new - but the object managed by the vector is not allocated like that; instead, vector grabs a chunk of memory from the allocator (as big as it thinks it's sensible) and copies there the elements that are pushed into it using placement new; so, not only you are freeing memory that you don't own, you are also using the wrong method to free it.
If you need to remove an element from a vector, just use the vector::erase method.

If you do delete this in any method, you have to be sure that no one else calls any method ( for that matter any code) of the instance after that statement. This includes the destructor.
When you push the instance into a vector, while being destroyed, the vector calls the destructor for the instance, hence the double free
If you need a vector, you can push pointers to the instance and it would be fine.
However, as others have said DO NOT use delete this unless absolutely necessary
You would also have the problems if you just create an local instance of the class in a function. Most likely you did not see this behavior because your program finished before the scope of the local variable ended. If you tried this :
void func() {
MyClass myClass;
myClass.theBadFunc();
}
When this returns, you will have a core dump.

Does this resemble the code that you're describing?
struct MyClass {
void f() { delete this; }
};
int main() {
MyClass c;
std::vector<MyClass> v;
v.push_back(c);
c.f();
return 0;
}
The vector is irrelevant. The problem is that delete this calls the destructor for c and frees the memory where c was built. That memory is on the stack, and cannot be freed. Don't ever delete stack objects. The compiler generates code to clean them up when they go out of scope, in this case, at the end of main.

Related

deleting pointer to pointer is run-time error?

i have a simple question about pointers , why when i tried to delete a pointer that is pointing into a pointer (the small pointer is pointing into a new variable (new memory allocation )) i always receive a run-time error ?? (as shown below :)) )
#include <iostream>
using namespace std;
int main() {
int *a=new int;
*a=10;
int **aa=&a;
cout<<*a<<endl;
cout<<**aa<<endl;
delete aa;// when i comment this line the program work as well as expectied
return 0;
}
and how can i delete a pointer that is pointing into another pointer ??
i receive this error when i try to run the previous code
10
10
*** Error in `/home/abdullah/CLionProjects/tstt1/cmake-build-debug/tstt1': munmap_chunk(): invalid pointer: 0x00007ffef8e9dbb0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x70bfb)[0x7fa3a9c5ebfb]
/lib/x86_64-linux-gnu/libc.so.6(+0x76fc6)[0x7fa3a9c64fc6]
/home/abdullah/CLionProjects/tstt1/cmake-build-debug/tstt1(+0xa4e)[0x5590e44c0a4e]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf1)[0x7fa3a9c0e2e1]
/home/abdullah/CLionProjects/tstt1/cmake-build-debug/tstt1(+0x8ba)[0x5590e44c08ba]
======= Memory map: ========
5590e44c0000-5590e44c1000 r-xp 00000000 08:07 1836009 /home/abdullah/CLionProjects/tstt1/cmake-build-debug/tstt1
5590e46c0000-5590e46c1000 r--p 00000000 08:07 1836009 /home/abdullah/CLionProjects/tstt1/cmake-build-debug/tstt1
5590e46c1000-5590e46c2000 rw-p 00001000 08:07 1836009 /home/abdullah/CLionProjects/tstt1/cmake-build-debug/tstt1
5590e50f2000-5590e5124000 rw-p 00000000 00:00 0 [heap]
7fa3a9bee000-7fa3a9d83000 r-xp 00000000 08:07 2761474 /usr/lib/x86_64-linux-gnu/libc-2.24.so
7fa3a9d83000-7fa3a9f83000 ---p 00195000 08:07 2761474 /usr/lib/x86_64-linux-gnu/libc-2.24.so
7fa3a9f83000-7fa3a9f87000 r--p 00195000 08:07 2761474 /usr/lib/x86_64-linux-gnu/libc-2.24.so
7fa3a9f87000-7fa3a9f89000 rw-p 00199000 08:07 2761474 /usr/lib/x86_64-linux-gnu/libc-2.24.so
7fa3a9f89000-7fa3a9f8d000 rw-p 00000000 00:00 0
7fa3a9f8d000-7fa3a9fa3000 r-xp 00000000 08:07 2761798 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
7fa3a9fa3000-7fa3aa1a2000 ---p 00016000 08:07 2761798 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
7fa3aa1a2000-7fa3aa1a3000 r--p 00015000 08:07 2761798 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
7fa3aa1a3000-7fa3aa1a4000 rw-p 00016000 08:07 2761798 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
7fa3aa1a4000-7fa3aa2a7000 r-xp 00000000 08:07 2762304 /usr/lib/x86_64-linux-gnu/libm-2.24.so
7fa3aa2a7000-7fa3aa4a6000 ---p 00103000 08:07 2762304 /usr/lib/x86_64-linux-gnu/libm-2.24.so
7fa3aa4a6000-7fa3aa4a7000 r--p 00102000 08:07 2762304 /usr/lib/x86_64-linux-gnu/libm-2.24.so
7fa3aa4a7000-7fa3aa4a8000 rw-p 00103000 08:07 2762304 /usr/lib/x86_64-linux-gnu/libm-2.24.so
7fa3aa4a8000-7fa3aa61a000 r-xp 00000000 08:07 2762793 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22
7fa3aa61a000-7fa3aa81a000 ---p 00172000 08:07 2762793 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22
7fa3aa81a000-7fa3aa824000 r--p 00172000 08:07 2762793 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22
7fa3aa824000-7fa3aa826000 rw-p 0017c000 08:07 2762793 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22
7fa3aa826000-7fa3aa82a000 rw-p 00000000 00:00 0
7fa3aa82a000-7fa3aa84d000 r-xp 00000000 08:07 2761022 /usr/lib/x86_64-linux-gnu/ld-2.24.so
7fa3aaa2e000-7fa3aaa32000 rw-p 00000000 00:00 0
7fa3aaa49000-7fa3aaa4d000 rw-p 00000000 00:00 0
7fa3aaa4d000-7fa3aaa4e000 r--p 00023000 08:07 2761022 /usr/lib/x86_64-linux-gnu/ld-2.24.so
7fa3aaa4e000-7fa3aaa4f000 rw-p 00024000 08:07 2761022 /usr/lib/x86_64-linux-gnu/ld-2.24.so
7fa3aaa4f000-7fa3aaa50000 rw-p 00000000 00:00 0
7ffef8e7e000-7ffef8e9f000 rw-p 00000000 00:00 0 [stack]
7ffef8ed9000-7ffef8edc000 r--p 00000000 00:00 0 [vvar]
7ffef8edc000-7ffef8ede000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
any ideas ? :(
aa is pointing to a which is a stack variable. You can only delete objects that were created using new.
Are you trying to delete the int that you created using new? In that case you would want to try delete *aa.

Error message glibc detected Malloc(): memory corruption (fast)

I recently got this error. The weird thing is, that I am not always getting this error message...
*** glibc detected *** ./a.out: malloc(): memory corruption (fast): 0x0000000002134dc0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x76a16)[0x7fa62b164a16]
/lib/x86_64-linux-gnu/libc.so.6(+0x7a2f8)[0x7fa62b1682f8]
/lib/x86_64-linux-gnu/libc.so.6(__libc_malloc+0x70)[0x7fa62b1698a0]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_Znwm+0x1d)[0x7fa62b97607d]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZNSs4_Rep9_S_createEmmRKSaIcE+0x59)[0x7fa62b9d1999]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZNSs4_Rep8_M_cloneERKSaIcEm+0x28)[0x7fa62b9d2708]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZNSs7reserveEm+0x30)[0x7fa62b9d27f0]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZNSs6appendEPKcm+0xb5)[0x7fa62b9d2ab5]
./a.out[0x40758f]
./a.out[0x403279]
./a.out[0x405202]
./a.out[0x406332]
./a.out[0x406c90]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)[0x7fa62b10cead]
./a.out[0x402189]
======= Memory map: ========
00400000-0040e000 r-xp 00000000 08:05 6166978 /root/tradingbot/bot2/a.out
0060d000-0060e000 rw-p 0000d000 08:05 6166978 /root/tradingbot/bot2/a.out
02132000-02153000 rw-p 00000000 00:00 0 [heap]
7fa624000000-7fa624021000 rw-p 00000000 00:00 0
7fa624021000-7fa628000000 ---p 00000000 00:00 0
7fa62b0ee000-7fa62b270000 r-xp 00000000 08:05 12715768 /lib/x86_64-linux-gnu/libc-2.13.so
7fa62b270000-7fa62b470000 ---p 00182000 08:05 12715768 /lib/x86_64-linux-gnu/libc-2.13.so
7fa62b470000-7fa62b474000 r--p 00182000 08:05 12715768 /lib/x86_64-linux-gnu/libc-2.13.so
7fa62b474000-7fa62b475000 rw-p 00186000 08:05 12715768 /lib/x86_64-linux-gnu/libc-2.13.so
7fa62b475000-7fa62b47a000 rw-p 00000000 00:00 0
7fa62b47a000-7fa62b48f000 r-xp 00000000 08:05 12715492 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fa62b48f000-7fa62b68f000 ---p 00015000 08:05 12715492 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fa62b68f000-7fa62b690000 rw-p 00015000 08:05 12715492 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fa62b690000-7fa62b711000 r-xp 00000000 08:05 12715766 /lib/x86_64-linux-gnu/libm-2.13.so
7fa62b711000-7fa62b910000 ---p 00081000 08:05 12715766 /lib/x86_64-linux-gnu/libm-2.13.so
7fa62b910000-7fa62b911000 r--p 00080000 08:05 12715766 /lib/x86_64-linux-gnu/libm-2.13.so
7fa62b911000-7fa62b912000 rw-p 00081000 08:05 12715766 /lib/x86_64-linux-gnu/libm-2.13.so
7fa62b912000-7fa62b9fa000 r-xp 00000000 08:05 7345862 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
7fa62b9fa000-7fa62bbfa000 ---p 000e8000 08:05 7345862 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
7fa62bbfa000-7fa62bc02000 r--p 000e8000 08:05 7345862 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
7fa62bc02000-7fa62bc04000 rw-p 000f0000 08:05 7345862 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
7fa62bc04000-7fa62bc19000 rw-p 00000000 00:00 0
7fa62bc19000-7fa62bc39000 r-xp 00000000 08:05 12715773 /lib/x86_64-linux-gnu/ld-2.13.so
7fa62be10000-7fa62be15000 rw-p 00000000 00:00 0
7fa62be35000-7fa62be38000 rw-p 00000000 00:00 0
7fa62be38000-7fa62be39000 r--p 0001f000 08:05 12715773 /lib/x86_64-linux-gnu/ld-2.13.so
7fa62be39000-7fa62be3a000 rw-p 00020000 08:05 12715773 /lib/x86_64-linux-gnu/ld-2.13.so
7fa62be3a000-7fa62be3b000 rw-p 00000000 00:00 0
7fffb0149000-7fffb016a000 rw-p 00000000 00:00 0 [stack]
7fffb019f000-7fffb01a1000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted
Here is what I was doing...
I am creating n objects of a class dynamically and storing them in a vector (C++). Then with an iterator I access each object, and deference it to access the object's members. I am also reading some text files, so edited them by hand during runtime. I don't know which part of the code I should place here, but this is where it crashed exactly:
if( last_op_number == 1 ){
it = n_bots.end();// Grabs iterator and go to the end of the vector; This is where the last OP1 bot is located
bot *botop1 = &(*it); // Dereference iterator to have a pointer to that specific bot
/* 3) Set the real buy and sell prices */
botop1->real_bpsp(price_ex1,price_ex2);
}
// Clear text files
OKC->clear_pos();
OKC2->clear_pos();
updates_balance(); // Updates balances
green_light = 1; // Tell bot manager that we are good to go!
Any ideas of what's going on?
Thank you!
You should use n_bots.back() instead of n_bots.end().

double free or corruption while reading/writing from file

Here's my code:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
class student{
private:
string nm, addr;
int roll;
public:
student(string name="a", string address="a", int rollnumber=0):
nm(name), addr(address), roll(rollnumber){}
void show(){
cout<<nm<<endl<<addr<<endl<<roll<<endl;
}
};
int main(){
fstream file1;
file1.open("obj.file", ios::in|ios::out|ios::binary|ios::ate);
student s1("cipher", "MyAddress", 21);
student s2;
file1.write(reinterpret_cast<char *>(&s1), sizeof(s1));
file1.flush();
file1.seekg(0,ios::beg);
file1.read(reinterpret_cast<char *>(&s2), sizeof(s2));
s2.show();
return 0;
}
And here's what happened. I could not get any lead why did the error occur?
$ ./fh2
cipher
MyAddress
21
*** Error in `./fh2': double free or corruption (fasttop): 0x08e14178 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x767c2)[0xb756f7c2]
/lib/i386-linux-gnu/libc.so.6(+0x77510)[0xb7570510]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdlPv+0x1f)[0xb7713a3f]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZNSs4_Rep10_M_destroyERKSaIcE+0x1b)[0xb777845b]
/usr/lib/i386-linux-gnu/libstdc++.so.6(+0x4671a)[0xb771171a]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZNSsD1Ev+0x2e)[0xb77784be]
./fh2[0x804902d]
./fh2[0x8048dc0]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0xb7512905]
./fh2[0x8048a91]
======= Memory map: ========
08048000-0804a000 r-xp 00000000 08:05 2793609 /home/cipher/cipher-codes/practice-for-cpp-exam/fh2
0804a000-0804b000 r--p 00001000 08:05 2793609 /home/cipher/cipher-codes/practice-for-cpp-exam/fh2
0804b000-0804c000 rw-p 00002000 08:05 2793609 /home/cipher/cipher-codes/practice-for-cpp-exam/fh2
08e12000-08e33000 rw-p 00000000 00:00 0 [heap]
b74b4000-b74b6000 rw-p 00000000 00:00 0
b74b6000-b74f7000 r-xp 00000000 08:05 11707309 /lib/i386-linux-gnu/libm-2.17.so
b74f7000-b74f8000 r--p 00040000 08:05 11707309 /lib/i386-linux-gnu/libm-2.17.so
b74f8000-b74f9000 rw-p 00041000 08:05 11707309 /lib/i386-linux-gnu/libm-2.17.so
b74f9000-b76a7000 r-xp 00000000 08:05 11707258 /lib/i386-linux-gnu/libc-2.17.so
b76a7000-b76a9000 r--p 001ae000 08:05 11707258 /lib/i386-linux-gnu/libc-2.17.so
b76a9000-b76aa000 rw-p 001b0000 08:05 11707258 /lib/i386-linux-gnu/libc-2.17.so
b76aa000-b76ae000 rw-p 00000000 00:00 0
b76ae000-b76c9000 r-xp 00000000 08:05 11706373 /lib/i386-linux-gnu/libgcc_s.so.1
b76c9000-b76ca000 r--p 0001a000 08:05 11706373 /lib/i386-linux-gnu/libgcc_s.so.1
b76ca000-b76cb000 rw-p 0001b000 08:05 11706373 /lib/i386-linux-gnu/libgcc_s.so.1
b76cb000-b77a8000 r-xp 00000000 08:05 8300861 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.18
b77a8000-b77ac000 r--p 000dc000 08:05 8300861 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.18
b77ac000-b77ad000 rw-p 000e0000 08:05 8300861 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.18
b77ad000-b77b4000 rw-p 00000000 00:00 0
b77ca000-b77ce000 rw-p 00000000 00:00 0
b77ce000-b77cf000 r-xp 00000000 00:00 0 [vdso]
b77cf000-b77ef000 r-xp 00000000 08:05 11707234 /lib/i386-linux-gnu/ld-2.17.so
b77ef000-b77f0000 r--p 0001f000 08:05 11707234 /lib/i386-linux-gnu/ld-2.17.so
b77f0000-b77f1000 rw-p 00020000 08:05 11707234 /lib/i386-linux-gnu/ld-2.17.so
bfd7c000-bfd9d000 rw-p 00000000 00:00 0 [stack]
[1] 24855 abort (core dumped) ./fh2
You're copying s1 to s2 (and it's associated data members) byte-for-byte. That works for POD (plain old data) types, but that is not guaranteed to work for complex types. Your strings cannot be copied in this manner. When their destructors run they will likely be trying to deallocate the same piece of memory (their internal data stores), i.e., a double delete.
You're circumventing the copy mechanism that the string class has in place precisely to avoid this sort of scenario. It's no different than calling memcpy or something similar. Won't work. You simply cannot persist non-POD types like this.
Even if you didn't get an error, it would still be wrong in a logical sense. Think about it; those strings are going to allocate their internal memory store dynamically, i.e., they will store a pointer to some chunk of memory. That pointer would not be valid once the string's destructor ran, and it certainly wouldn't be valid if, say, you decided to deserialize that file a week from now.
When you write the contents of s1 you are actually copying the pointer inside the string. You then write this into s2's string. When s1 and s2 call their deconstructor they will both free the same string pointer, which is your double free.

Deletion of Pointers Issue

I am having trouble deleting my pointers that I have created. The program creates a double pointer to point to the threads. Then it creates threads dynamically. At the end it deletes them but I am getting a glibc error. It uses boost to create the threads. What is really puzzling is that I delete a similar double pointer the same exact way and that executes fine. The issue is at the end of the code block under the heading of /*clean up*/:
boost :: thread** thrds;
//create threads and bind to p_variantforloop_t
thrds = new boost::thread*[numThreads];
for (int i = 1; i <= numThreads; i++)
thrds[i] = new boost::thread(boost::bind(&p_variantforloop_t,
E, A, D, (i*n-n)/i ,(i*n)/n, numThreads, n));
/* join threads */
for (int i = 0; i < numThreads; i++)
thrds[i]->join();
/* cleanup */
for (int i = 0; i < numThreads; i++)
delete thrds[i];
delete[] thrds;
the error is:
*** glibc detected *** ./hw9: munmap_chunk(): invalid pointer: 0x0957d480 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(+0x6b591)[0x264591]
/lib/tls/i686/cmov/libc.so.6(+0x6c80e)[0x26580e]
/usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0x529741]
./hw9[0x804a0d1]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0x20fbd6]
./hw9[0x8049871]
======= Memory map: ========
001f9000-0034c000 r-xp 00000000 08:02 1128663 /lib/tls/i686/cmov/libc-2.11.1.so
0034c000-0034d000 ---p 00153000 08:02 1128663 /lib/tls/i686/cmov/libc-2.11.1.so
0034d000-0034f000 r--p 00153000 08:02 1128663 /lib/tls/i686/cmov/libc-2.11.1.so
0034f000-00350000 rw-p 00155000 08:02 1128663 /lib/tls/i686/cmov/libc-2.11.1.so
00350000-00353000 rw-p 00000000 00:00 0
0046e000-00557000 r-xp 00000000 08:02 982712 /usr/lib/libstdc++.so.6.0.13
00557000-00558000 ---p 000e9000 08:02 982712 /usr/lib/libstdc++.so.6.0.13
00558000-0055c000 r--p 000e9000 08:02 982712 /usr/lib/libstdc++.so.6.0.13
0055c000-0055d000 rw-p 000ed000 08:02 982712 /usr/lib/libstdc++.so.6.0.13
0055d000-00564000 rw-p 00000000 00:00 0
005ad000-005d1000 r-xp 00000000 08:02 1130719 /lib/tls/i686/cmov/libm-2.11.1.so
005d1000-005d2000 r--p 00023000 08:02 1130719 /lib/tls/i686/cmov/libm-2.11.1.so
005d2000-005d3000 rw-p 00024000 08:02 1130719 /lib/tls/i686/cmov/libm-2.11.1.so
00950000-00965000 r-xp 00000000 08:02 1130743 /lib/tls/i686/cmov/libpthread-2.11.1.so
00965000-00966000 r--p 00014000 08:02 1130743 /lib/tls/i686/cmov/libpthread-2.11.1.so
00966000-00967000 rw-p 00015000 08:02 1130743 /lib/tls/i686/cmov/libpthread-2.11.1.so
00967000-00969000 rw-p 00000000 00:00 0
00a67000-00a7a000 r-xp 00000000 08:02 176445 /usr/lib/libboost_thread.so.1.40.0
00a7a000-00a7b000 r--p 00013000 08:02 176445 /usr/lib/libboost_thread.so.1.40.0
00a7b000-00a7c000 rw-p 00014000 08:02 176445 /usr/lib/libboost_thread.so.1.40.0
00bc7000-00be2000 r-xp 00000000 08:02 1128318 /lib/ld-2.11.1.so
00be2000-00be3000 r--p 0001a000 08:02 1128318 /lib/ld-2.11.1.so
00be3000-00be4000 rw-p 0001b000 08:02 1128318 /lib/ld-2.11.1.so
00c34000-00c3b000 r-xp 00000000 08:02 1130745 /lib/tls/i686/cmov/librt-2.11.1.so
00c3b000-00c3c000 r--p 00006000 08:02 1130745 /lib/tls/i686/cmov/librt-2.11.1.so
00c3c000-00c3d000 rw-p 00007000 08:02 1130745 /lib/tls/i686/cmov/librt-2.11.1.so
00ccf000-00cd0000 r-xp 00000000 00:00 0 [vdso]
00e85000-00ea2000 r-xp 00000000 08:02 1128359 /lib/libgcc_s.so.1
00ea2000-00ea3000 r--p 0001c000 08:02 1128359 /lib/libgcc_s.so.1
00ea3000-00ea4000 rw-p 0001d000 08:02 1128359 /lib/libgcc_s.so.1
08048000-0804e000 r-xp 00000000 00:1d 10184 /home/tparisi/Desktop/source_code_hw5/hw9
0804e000-0804f000 r--p 00005000 00:1d 10184 /home/tparisi/Desktop/source_code_hw5/hw9
0804f000-08050000 rw-p 00006000 00:1d 10184 /home/tparisi/Desktop/source_code_hw5/hw9
0957d000-0959e000 rw-p 00000000 00:00 0 [heap]
b68bf000-b68c0000 ---p 00000000 00:00 0
b68c0000-b70c0000 rw-p 00000000 00:00 0
b70c0000-b70c1000 ---p 00000000 00:00 0
b70c1000-b78c4000 rw-p 00000000 00:00 0
b78e8000-b78eb000 rw-p 00000000 00:00 0
bfc07000-bfc1c000 rw-p 00000000 00:00 0 [stack]
Aborted
You omit first element of the array when creating thread object. It stays with uninitialized pointer value, causing the invalid pointer error later.
There is also an issue of writing to memory immediately after the last element of array, which you also do in the problematic loop (i.e. the first for in your code).

Weird stack smash error - caused by unused, uninitialized member variable

Today I had a fun bug where apparently my stack got smashed, overriding the G++ return-point canary (I think that's the protection used).
My offending class was this:
class ClientSendContext : public SendContext
{
public:
ClientSendContext(UdpClient& client);
void send(boost::asio::const_buffer buffer);
private:
boost::asio::ip::udp::endpoint endpoint;
UdpClient& client;
};
The thing was, the client variable was initialized in the initializer list, but not the endpoint (it's not used in the ClientSendContext, since it only sends to one endpoint, but no matter). The smash-stack occured once every three times I executed my test (or something like that) which is weird, since I do the exact same thing (must be thread timing issue).
However, as soon I remove the endpoint variable, it works fine! How can this be? It wasn't used in any way, g++ didn't warn me about it... Valgrind was quiet aswell.
(Could someone with high rep please edit my question and add stack-smash or something like that as a tag?)
Alright, an update with more code, posted on pastebin:
http://pastebin.com/xiWx8xjV
That should be all the methods called. The inner most send method is part of a templated class. The same send method works fine when the UdpServer uses it.. I'm just a bit stumped right now.
EDIT: Code now put directly here:
void doTest(bool& failed)
{
ReceiveHelper helper(failed);
boost::threadpool::pool pool(2);
int port = 55600;
boost::asio::io_service service;
udp::endpoint thisPoint = udp::endpoint(address::from_string("127.0.0.1"),
port);
udp::endpoint receivePoint;
udp::socket socket(service, thisPoint);
socket.async_receive_from(boost::asio::buffer(helper.buffer), receivePoint, boost::bind(&ReceiveHelper::handleReceive,
&helper, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
pool.schedule(boost::bind(&boost::asio::io_service::run, &service));
voip::network::client::UdpClient client;
client.connect(thisPoint);
client.send(1, "Hello!");
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
service.stop();
}
class ReceiveHelper {
private:
bool& failed;
public:
ReceiveHelper(bool & failed) : failed(failed), buffer()
{
}
boost::array<uint8_t, BUF_SIZE> buffer;
void handleReceive(const boost::system::error_code & error, size_t numBytes)
{
if(numBytes != 8)
return;
if(std::string((char*)buffer.c_array(), 6) != "Hello!")
return;
failed = false;
}
};
void UdpClient::send(uint8_t handler, std::string message)
{ <-------------------------------------------------------------------------------------- Canary at this point fails
ClientSendContext context(*this);
ClientConnection::send(context, handler, message);
} <-------------------------------------------------------------------------------------- Canary at this point fails
void send(SendContext & sendContext, uint8_t handler, std::string & message)
{
uint8_t *array = new uint8_t[message.size() + 2];
memcpy(array, message.c_str(), message.size());
boost::asio::mutable_buffer buffer(array, message.size() + 2);
prepareMessage(handler, buffer);
sendContext.send(buffer);
delete[] array;
}
size_t prepareMessage(uint8_t handler, boost::asio::mutable_buffer message)
{
size_t messageLength = boost::asio::buffer_size(message);
uint8_t* data = boost::asio::buffer_cast<uint8_t*>(message);
data[messageLength - 1] = network::handler;
data[messageLength - 2] = handler;
return messageLength;
}
And the error message:
*** stack smashing detected ***: ./testclient terminated
======= Backtrace: =========
/lib/libc.so.6(__fortify_fail+0x37)[0x58e9537]
/lib/libc.so.6(__fortify_fail+0x0)[0x58e9500]
./testclient(_ZN4voip7network6client9UdpClient4sendEhSs+0x85)[0x46b449]
./testclient(_ZN4voip4test6client18SuiteTestUdpClient6doTestERb+0x2dd)[0x44c7c1]
./testclient(_ZNK4voip4test6client18SuiteTestUdpClient17TestClientCanSend7RunImplEv+0x2f)[0x44c957]
./testclient(_ZN8UnitTest11ExecuteTestINS_4TestEEEvRT_RKNS_11TestDetailsE+0x9a)[0x469551]
./testclient(_ZN8UnitTest4Test3RunEv+0x23)[0x46920f]
./testclient(_ZNK8UnitTest10TestRunner7RunTestEPNS_11TestResultsEPNS_4TestEi+0x7c)[0x469b74]
./testclient(_ZNK8UnitTest10TestRunner10RunTestsIfINS_4TrueEEEiRKNS_8TestListEPKcRKT_i+0x8f)[0x469ddb]
./testclient(_ZN8UnitTest11RunAllTestsEv+0x53)[0x4697b7]
./testclient(main+0x9)[0x44ca62]
/lib/libc.so.6(__libc_start_main+0xfe)[0x5808d8e]
./testclient[0x44c429]
======= Memory map: ========
00400000-00494000 r-xp 00000000 08:05 150971 /home/max/Documents/c++proj/voip/build/testclient
00693000-00694000 r--p 00093000 08:05 150971 /home/max/Documents/c++proj/voip/build/testclient
00694000-00695000 rw-p 00094000 08:05 150971 /home/max/Documents/c++proj/voip/build/testclient
00695000-00696000 rw-p 00000000 00:00 0
04000000-04020000 r-xp 00000000 08:05 560792 /lib/ld-2.12.1.so
04020000-04022000 rw-p 00000000 00:00 0
0403f000-04045000 rw-p 00000000 00:00 0
04220000-04221000 r--p 00020000 08:05 560792 /lib/ld-2.12.1.so
04221000-04222000 rw-p 00021000 08:05 560792 /lib/ld-2.12.1.so
04222000-04223000 rw-p 00000000 00:00 0
04223000-04224000 rwxp 00000000 00:00 0
04a23000-04a24000 r-xp 00000000 08:05 145700 /usr/lib/valgrind/vgpreload_core-amd64-linux.so
04a24000-04c23000 ---p 00001000 08:05 145700 /usr/lib/valgrind/vgpreload_core-amd64-linux.so
04c23000-04c24000 r--p 00000000 08:05 145700 /usr/lib/valgrind/vgpreload_core-amd64-linux.so
04c24000-04c25000 rw-p 00001000 08:05 145700 /usr/lib/valgrind/vgpreload_core-amd64-linux.so
04c25000-04c2d000 r-xp 00000000 08:05 145715 /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
04c2d000-04e2c000 ---p 00008000 08:05 145715 /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
04e2c000-04e2d000 r--p 00007000 08:05 145715 /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
04e2d000-04e2e000 rw-p 00008000 08:05 145715 /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
04e2e000-04e46000 r-xp 00000000 08:05 557639 /lib/libpthread-2.12.1.so
04e46000-05045000 ---p 00018000 08:05 557639 /lib/libpthread-2.12.1.so
05045000-05046000 r--p 00017000 08:05 557639 /lib/libpthread-2.12.1.so
05046000-05047000 rw-p 00018000 08:05 557639 /lib/libpthread-2.12.1.so
05047000-0504b000 rw-p 00000000 00:00 0
0504b000-05133000 r-xp 00000000 08:05 656172 /usr/lib/libstdc++.so.6.0.14
05133000-05332000 ---p 000e8000 08:05 656172 /usr/lib/libstdc++.so.6.0.14
05332000-0533a000 r--p 000e7000 08:05 656172 /usr/lib/libstdc++.so.6.0.14
0533a000-0533c000 rw-p 000ef000 08:05 656172 /usr/lib/libstdc++.so.6.0.14
0533c000-05351000 rw-p 00000000 00:00 0
05351000-053d3000 r-xp 00000000 08:05 560787 /lib/libm-2.12.1.so
053d3000-055d2000 ---p 00082000 08:05 560787 /lib/libm-2.12.1.so
055d2000-055d3000 r--p 00081000 08:05 560787 /lib/libm-2.12.1.so
055d3000-055d4000 rw-p 00082000 08:05 560787 /lib/libm-2.12.1.so
055d4000-055e9000 r-xp 00000000 08:05 521495 /lib/libgcc_s.so.1
055e9000-057e8000 ---p 00015000 08:05 521495 /lib/libgcc_s.so.1
057e8000-057e9000 r--p 00014000 08:05 521495 /lib/libgcc_s.so.1
057e9000-057ea000 rw-p 00015000 08:05 521495 /lib/libgcc_s.so.1
057ea000-05964000 r-xp 00000000 08:05 557476 /lib/libc-2.12.1.so
05964000-05b63000 ---p 0017a000 08:05 557476 /lib/libc-2.12.1.so
05b63000-05b67000 r--p 00179000 08:05 557476 /lib/libc-2.12.1.so
05b67000-05b68000 rw-p 0017d000 08:05 557476 /lib/libc-2.12.1.so
05b68000-05b6d000 rw-p 00000000 00:00 0
05b6d000-05f6d000 rwxp 00000000 00:00 0
05f6d000-05f6e000 ---p 00000000 00:00 0
05f6e000-0676e000 rw-p 00000000 00:00 0
0676e000-0676f000 ---p 00000000 00:00 0
0676f000-06f6f000 rw-p 00000000 00:00 0
06f6f000-06f70000 ---p 00000000 00:00 0
06f70000-07770000 rw-p 00000000 00:00 0
07770000-07771000 ---p 00000000 00:00 0
07771000-07f71000 rw-p 00000000 00:00 0
38000000-381fc000 r-xp 00200000 08:05 145710 /usr/lib/valgrind/memcheck-amd64-linux
383fb000-383fe000 rw-p 003fb000 08:05 145710 /usr/lib/valgrind/memcheck-amd64-linux
383fe000-3927e000 rw-p 00000000 00:00 0
402001000-403272000 rwxp 00000000 00:00 0
403272000-403274000 ---p 00000000 00:00 0
403274000-403374000 rwxp 00000000 00:00 0
403374000-403376000 ---p 00000000 00:00 0
403376000-40583e000 rwxp 00000000 00:00 0
40583e000-405840000 ---p 00000000 00:00 0
405840000-405940000 rwxp 00000000 00:00 0
405940000-405942000 ---p 00000000 00:00 0
405942000-405946000 rwxp 00000000 00:00 0
405946000-405948000 ---p 00000000 00:00 0
405948000-405a48000 rwxp 00000000 00:00 0
405a48000-405a4a000 ---p 00000000 00:00 0
405a4a000-405a4e000 rwxp 00000000 00:00 0
405a4e000-405a50000 ---p 00000000 00:00 0
405a50000-405b50000 rwxp 00000000 00:00 0
405b50000-405b52000 ---p 00000000 00:00 0
405b52000-405b5a000 rwxp 00000000 00:00 0
405b5a000-405b5c000 ---p 00000000 00:00 0
405b5c000-405c5c000 rwxp 00000000 00:00 0
405c5c000-405c5e000 ---p 00000000 00:00 0
405c5e000-405c62000 rwxp 00000000 00:00 0
7feffd000-7ff001000 rwxp 00000000 00:00 0
7fffb9f36000-7fffb9f57000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
this error is (almost always) caused by appending more elements to an array/vector than said array/vector has been declared as having. therefore i would pay specific attention to all char and uint8 arrays in your code.
though the dump might make sense for someone who understands linux c++ profoundly, it makes no sense for mere mortals and debugging using it is not the fastest solution.
i like the old school approach: print flags to show up to what point your program goes without exceptions. you can usually isolate the offending array(s) this way quite quickly.
as an example, i was having the exact same problem with this code:
std::string GetTimeStringFromDump(unsigned char *bufDumpIn, int startDate) {
unsigned char bufOut[6];
for (int counter02=0;counter02<12;counter02++) {
bufOut[counter02] = bufDumpIn[counter02+startDate];
}
std::string unixTimeOut = GetTimeStringNew(bufOut);
std::cout << "UnixTimeOUT: " << unixTimeOut << std::endl;
return unixTimeOut;
}
the weirdest thing was that the error did NOT occur when i assigned a string that had 12 characters to bufOut (declared as having 6 elements), but rather after
return unixTimeOut;
nevertheless, i changed the declaration to
unsigned char bufOut[12];
and the problem was solved.