I was trying to make a program that replaces characters e with * on a string that has the most e's,but I'm getting a random free(): invalid pointer error whenever I run this program:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
const char char1 = 'e', char2 = '*';
int N, mostchars = 0, its;
cout << "N = ";
cin >> N;
string strings[N];
for(int i = 1; i <= N; i++)
{
cin >> strings[i];
if(mostchars < count(strings[i].begin(), strings[i].end(), char1))
{
mostchars = count(strings[i].begin(), strings[i].end(), char1);
its = i;
}
}
replace(strings[its].begin(), strings[its].end(), char1, char2);
cout << strings[its] << endl;
return 0;
}
And here's the gdb output:
*** Error in `/home/hiddendirishidden/STRING/bin/Debug/STRING': free(): invalid pointer: 0x00007fffffffe6a0 ***
======= Backtrace: =========
/usr/lib/libc.so.6(+0x6f364)[0x7ffff720a364]
/usr/lib/libc.so.6(+0x74d96)[0x7ffff720fd96]
/usr/lib/libc.so.6(+0x7557e)[0x7ffff721057e]
/usr/lib/libstdc++.so.6(_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_mutateEmmPKcm+0xfd)[0x7ffff7b765dd]
/usr/lib/libstdc++.so.6(_ZStrsIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_stringIS4_S5_T1_EE+0x314)[0x7ffff7afd624]
/home/hiddendirishidden/STRING/bin/Debug/STRING[0x400e13]
/usr/lib/libc.so.6(__libc_start_main+0xf0)[0x7ffff71bb710]
/home/hiddendirishidden/STRING/bin/Debug/STRING[0x400c39]
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:21 1452363 /home/hiddendirishidden/STRING/bin/Debug/STRING
00601000-00602000 rw-p 00001000 08:21 1452363 /home/hiddendirishidden/STRING/bin/Debug/STRING
00602000-00634000 rw-p 00000000 00:00 0 [heap]
7ffff0000000-7ffff0021000 rw-p 00000000 00:00 0
7ffff0021000-7ffff4000000 ---p 00000000 00:00 0
7ffff719b000-7ffff7333000 r-xp 00000000 08:21 396432 /usr/lib/libc-2.23.so
7ffff7333000-7ffff7532000 ---p 00198000 08:21 396432 /usr/lib/libc-2.23.so
7ffff7532000-7ffff7536000 r--p 00197000 08:21 396432 /usr/lib/libc-2.23.so
7ffff7536000-7ffff7538000 rw-p 0019b000 08:21 396432 /usr/lib/libc-2.23.so
7ffff7538000-7ffff753c000 rw-p 00000000 00:00 0
7ffff753c000-7ffff7552000 r-xp 00000000 08:21 396763 /usr/lib/libgcc_s.so.1
7ffff7552000-7ffff7751000 ---p 00016000 08:21 396763 /usr/lib/libgcc_s.so.1
7ffff7751000-7ffff7752000 rw-p 00015000 08:21 396763 /usr/lib/libgcc_s.so.1
7ffff7752000-7ffff7855000 r-xp 00000000 08:21 396490 /usr/lib/libm-2.23.so
7ffff7855000-7ffff7a55000 ---p 00103000 08:21 396490 /usr/lib/libm-2.23.so
7ffff7a55000-7ffff7a56000 r--p 00103000 08:21 396490 /usr/lib/libm-2.23.so
7ffff7a56000-7ffff7a57000 rw-p 00104000 08:21 396490 /usr/lib/libm-2.23.so
7ffff7a57000-7ffff7bc9000 r-xp 00000000 08:21 396798 /usr/lib/libstdc++.so.6.0.21
7ffff7bc9000-7ffff7dc9000 ---p 00172000 08:21 396798 /usr/lib/libstdc++.so.6.0.21
7ffff7dc9000-7ffff7dd3000 r--p 00172000 08:21 396798 /usr/lib/libstdc++.so.6.0.21
7ffff7dd3000-7ffff7dd5000 rw-p 0017c000 08:21 396798 /usr/lib/libstdc++.so.6.0.21
7ffff7dd5000-7ffff7dd9000 rw-p 00000000 00:00 0
7ffff7dd9000-7ffff7dfc000 r-xp 00000000 08:21 396431 /usr/lib/ld-2.23.so
7ffff7fc5000-7ffff7fcb000 rw-p 00000000 00:00 0
7ffff7ff7000-7ffff7ff8000 rw-p 00000000 00:00 0
7ffff7ff8000-7ffff7ffa000 r--p 00000000 00:00 0 [vvar]
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00023000 08:21 396431 /usr/lib/ld-2.23.so
7ffff7ffd000-7ffff7ffe000 rw-p 00024000 08:21 396431 /usr/lib/ld-2.23.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Program received signal SIGABRT, Aborted.
0x00007ffff71ce2a8 in raise () from /usr/lib/libc.so.6
I'm not sure why that happens. Maybe I did something wrong, after all this is the first time I'm trying out the algorithm library.
In
for(int i = 1; i <= N; i++)
You are using 1-based index. strings only has elements indexed from 0 to N-1, strings[N] is an invalid access.
C++ convention is 0-based indexes. Do
for(int i = 0; i < N; ++i)
You also may like to initialize variables and check for errors on input.
You used a variable to determine the length of an array. You cannot do this safely in C++.
Use std::vector<std::string> instead of std::string[N].
Furthermore, your loop goes 1 → N, instead of the correct 0 → N-1. That means the std::string you're trying to access on the final iteration doesn't exist, and the various allocations that the std::string performs internally are therefore broken.
Related
I was trying to solve a hackerearth problems to understand c++ better.
The Task is as follows :
The first line will consists of one integer T denoting the number of test cases.
For each test case:
The first line consists of two integers N and K, N being the number of elements in the array and K denotes the number of steps of rotation.
The next line consists of N space separated integers , denoting the elements of the array A.
So,If the input is like
1
5 2
1 2 3 4 5
The output should be
4 5 1 2 3
The code that i have written is as follows :
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
void ans(int r,vector<int> &a)
{
reverse(a.begin(),a.end());
reverse(a.begin(),a.begin()+r);
reverse(a.begin()+r,a.end());
}
int main() {
int testno;
cin>>testno;
int size,rotation,temp;
vector<vector<int>> arr(testno);
for(int i=0;i<testno;i++)
{
cin>>size;
cin>>rotation;
for(int j=0;j<size;j++)
{
cin>>temp;
arr[i].push_back(temp);
};
ans(rotation,arr[i]);
};
for(int i=0;i<arr.size();i++)
{
for(int j=0;j<arr[i].size();j++)
cout<<arr[i][j]<<" ";
cout<<"\n";
};
}
This code works fine for small test-cases or numbers.
But when the input is huge,I get the following error :
Execution failed.
Stack Trace:
*** Error in `/hackerearth/CPP17_a870_37de_35ba_2748/s_3a8f_d922_ff44_e648.cpp.out': malloc(): memory corruption (fast): 0x0000000001b0ad50 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777f5)[0x7f10c1df57f5]
/lib/x86_64-linux-gnu/libc.so.6(+0x82679)[0x7f10c1e00679]
/lib/x86_64-linux-gnu/libc.so.6(__libc_malloc+0x54)[0x7f10c1e021d4]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_Znwm+0x15)[0x7f10c2405c75]
/hackerearth/CPP17_a870_37de_35ba_2748/s_3a8f_d922_ff44_e648.cpp.out[0x400f62]
/hackerearth/CPP17_a870_37de_35ba_2748/s_3a8f_d922_ff44_e648.cpp.out[0x400bbb]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f10c1d9e840]
/hackerearth/CPP17_a870_37de_35ba_2748/s_3a8f_d922_ff44_e648.cpp.out[0x400d49]
======= Memory map: ========
00400000-00402000 r-xp 00000000 07:00 28 /hackerearth/CPP17_a870_37de_35ba_2748/s_3a8f_d922_ff44_e648.cpp.out
00601000-00602000 r--p 00001000 07:00 28 /hackerearth/CPP17_a870_37de_35ba_2748/s_3a8f_d922_ff44_e648.cpp.out
00602000-00603000 rw-p 00002000 07:00 28 /hackerearth/CPP17_a870_37de_35ba_2748/s_3a8f_d922_ff44_e648.cpp.out
01af8000-01b2a000 rw-p 00000000 00:00 0 [heap]
7f10bc000000-7f10bc021000 rw-p 00000000 00:00 0
7f10bc021000-7f10c0000000 ---p 00000000 00:00 0
7f10c1a75000-7f10c1b7d000 r-xp 00000000 ca:01 48154 /lib/x86_64-linux-gnu/libm-2.23.so
7f10c1b7d000-7f10c1d7c000 ---p 00108000 ca:01 48154 /lib/x86_64-linux-gnu/libm-2.23.so
7f10c1d7c000-7f10c1d7d000 r--p 00107000 ca:01 48154 /lib/x86_64-linux-gnu/libm-2.23.so
7f10c1d7d000-7f10c1d7e000 rw-p 00108000 ca:01 48154 /lib/x86_64-linux-gnu/libm-2.23.so
7f10c1d7e000-7f10c1f3e000 r-xp 00000000 ca:01 48130 /lib/x86_64-linux-gnu/libc-2.23.so
7f10c1f3e000-7f10c213e000 ---p 001c0000 ca:01 48130 /lib/x86_64-linux-gnu/libc-2.23.so
7f10c213e000-7f10c2142000 r--p 001c0000 ca:01 48130 /lib/x86_64-linux-gnu/libc-2.23.so
7f10c2142000-7f10c2144000 rw-p 001c4000 ca:01 48130 /lib/x86_64-linux-gnu/libc-2.23.so
7f10c2144000-7f10c2148000 rw-p 00000000 00:00 0
7f10c2148000-7f10c215f000 r-xp 00000000 ca:01 18214 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f10c215f000-7f10c235e000 ---p 00017000 ca:01 18214 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f10c235e000-7f10c235f000 r--p 00016000 ca:01 18214 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f10c235f000-7f10c2360000 rw-p 00017000 ca:01 18214 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f10c2360000-7f10c2533000 r-xp 00000000 ca:01 16581 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28
7f10c2533000-7f10c2732000 ---p 001d3000 ca:01 16581 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28
7f10c2732000-7f10c273d000 r--p 001d2000 ca:01 16581 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28
7f10c273d000-7f10c2740000 rw-p 001dd000 ca:01 16581 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28
7f10c2740000-7f10c2743000 rw-p 00000000 00:00 0
7f10c2743000-7f10c2769000 r-xp 00000000 ca:01 48198 /lib/x86_64-linux-gnu/ld-2.23.so
7f10c2948000-7f10c294e000 rw-p 00000000 00:00 0
7f10c2967000-7f10c2968000 rw-p 00000000 00:00 0
7f10c2968000-7f10c2969000 r--p 00025000 ca:01 48198 /lib/x86_64-linux-gnu/ld-2.23.so
7f10c2969000-7f10c296a000 rw-p 00026000 ca:01 48198 /lib/x86_64-linux-gnu/ld-2.23.so
7f10c296a000-7f10c296b000 rw-p 00000000 00:00 0
7fff76e54000-7fff76e75000 rw-p 00000000 00:00 0 [stack]
7fff76f09000-7fff76f0b000 r--p 00000000 00:00 0 [vvar]
7fff76f0b000-7fff76f0d000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
I don't understand why there is a runtime malloc error? What exactly is happening that is leading to this error for large inputs? Why is there memory corruption? Am I trying to access memory not allocated to me during the runtime? If so,Where? The link to the problem,if needed is : https://www.hackerearth.com/practice/codemonk/
Turns out some test cases had rotation higher than the size of vector.So just updated rotation to rotation%size. Working fine now.
This is part of a test for thread safety. I'm running an anonymous lambda in different threads.
I use the variable i as thread id.
Originally I passed every variable from main scope by using [&], but this corrupts the heap.
Solved it now by passing i by value, but for the life of me I can't figure out why this would cause problems on the heap since the threads are only reading i.
Can anyone explain?
Minimal compilable example producing error:
#include <thread>
#include <vector>
using namespace std;
int main(int argc, char** argv) {
vector<thread> threads;
vector<string> vec1;
vector<string> vec2;
for (int i = 0; i < 2; i++) {
threads.push_back(
thread([&vec1, &vec2, &i]() {
for (int j = 0; j < 10; j++) {
const string str = "foo";
if (i == 0) {
vec1.push_back(str);
} else {
vec2.push_back(str);
}
}
})
);
}
for (auto& thread : threads) {
thread.join();
}
return 0;
}
Output:
*** Error in `/vagrant/bin/TempFileTest': double free or corruption (fasttop): 0x00007f00240008c0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f002a0e97e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x8037a)[0x7f002a0f237a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7f002a0f653c]
/vagrant/bin/TempFileTest(_ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE19_M_emplace_back_auxIJRKS5_EEEvDpOT_+0x1a3)[0x4021b3]
/vagrant/bin/TempFileTest[0x401e83]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(+0xb8c80)[0x7f002a70ac80]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x76ba)[0x7f002a9db6ba]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x6d)[0x7f002a17941d]
======= Memory map: ========
00400000-00403000 r-xp 00000000 08:02 2622834 /vagrant/bin/TempFileTest
00602000-00603000 r--p 00002000 08:02 2622834 /vagrant/bin/TempFileTest
00603000-00604000 rw-p 00003000 08:02 2622834 /vagrant/bin/TempFileTest
02182000-021b4000 rw-p 00000000 00:00 0 [heap]
7f001c000000-7f001c021000 rw-p 00000000 00:00 0
7f001c021000-7f0020000000 ---p 00000000 00:00 0
7f0024000000-7f0024021000 rw-p 00000000 00:00 0
7f0024021000-7f0028000000 ---p 00000000 00:00 0
7f0028d67000-7f0028d68000 ---p 00000000 00:00 0
7f0028d68000-7f0029568000 rw-p 00000000 00:00 0
7f0029568000-7f0029569000 ---p 00000000 00:00 0
7f0029569000-7f0029d69000 rw-p 00000000 00:00 0
7f0029d69000-7f0029e71000 r-xp 00000000 00:32 313 /lib/x86_64-linux-gnu/libm-2.23.so
7f0029e71000-7f002a070000 ---p 00108000 00:32 313 /lib/x86_64-linux-gnu/libm-2.23.so
7f002a070000-7f002a071000 r--p 00107000 00:32 313 /lib/x86_64-linux-gnu/libm-2.23.so
7f002a071000-7f002a072000 rw-p 00108000 00:32 313 /lib/x86_64-linux-gnu/libm-2.23.so
7f002a072000-7f002a232000 r-xp 00000000 00:32 45 /lib/x86_64-linux-gnu/libc-2.23.so
7f002a232000-7f002a432000 ---p 001c0000 00:32 45 /lib/x86_64-linux-gnu/libc-2.23.so
7f002a432000-7f002a436000 r--p 001c0000 00:32 45 /lib/x86_64-linux-gnu/libc-2.23.so
7f002a436000-7f002a438000 rw-p 001c4000 00:32 45 /lib/x86_64-linux-gnu/libc-2.23.so
7f002a438000-7f002a43c000 rw-p 00000000 00:00 0
7f002a43c000-7f002a452000 r-xp 00000000 00:32 314 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f002a452000-7f002a651000 ---p 00016000 00:32 314 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f002a651000-7f002a652000 rw-p 00015000 00:32 314 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f002a652000-7f002a7c4000 r-xp 00000000 00:32 311 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f002a7c4000-7f002a9c4000 ---p 00172000 00:32 311 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f002a9c4000-7f002a9ce000 r--p 00172000 00:32 311 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f002a9ce000-7f002a9d0000 rw-p 0017c000 00:32 311 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f002a9d0000-7f002a9d4000 rw-p 00000000 00:00 0
7f002a9d4000-7f002a9ec000 r-xp 00000000 00:32 61 /lib/x86_64-linux-gnu/libpthread-2.23.so
7f002a9ec000-7f002abeb000 ---p 00018000 00:32 61 /lib/x86_64-linux-gnu/libpthread-2.23.so
7f002abeb000-7f002abec000 r--p 00017000 00:32 61 /lib/x86_64-linux-gnu/libpthread-2.23.so
7f002abec000-7f002abed000 rw-p 00018000 00:32 61 /lib/x86_64-linux-gnu/libpthread-2.23.so
7f002abed000-7f002abf1000 rw-p 00000000 00:00 0
7f002abf1000-7f002ac17000 r-xp 00000000 00:32 42 /lib/x86_64-linux-gnu/ld-2.23.so
7f002adf6000-7f002adfc000 rw-p 00000000 00:00 0
7f002ae15000-7f002ae16000 rw-p 00000000 00:00 0
7f002ae16000-7f002ae17000 r--p 00025000 00:32 42 /lib/x86_64-linux-gnu/ld-2.23.so
7f002ae17000-7f002ae18000 rw-p 00026000 00:32 42 /lib/x86_64-linux-gnu/ld-2.23.so
7f002ae18000-7f002ae19000 rw-p 00000000 00:00 0
7fff30694000-7fff306b5000 rw-p 00000000 00:00 0 [stack]
7fff30761000-7fff30763000 r--p 00000000 00:00 0 [vvar]
7fff30763000-7fff30765000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted (core dumped)
Minimal compilable example without error (notice no & on i):
#include <thread>
#include <vector>
using namespace std;
int main(int argc, char** argv) {
vector<thread> threads;
vector<string> vec1;
vector<string> vec2;
for (int i = 0; i < 2; i++) {
threads.push_back(
thread([&vec1, &vec2, i]() {
for (int j = 0; j < 10; j++) {
const string str = "foo";
if (i == 0) {
vec1.push_back(str);
} else {
vec2.push_back(str);
}
}
})
);
}
for (auto& thread : threads) {
thread.join();
}
return 0;
}
I'm using:
Ubuntu 16.04
gcc 5.4.0
Value of i changes at each iteration loop (in main thread) whereas you read it in other thread (without synchronization) -> UB.
Moreover, once the primary loop ends, you have dangling reference to i.
As a side note, you can spare yourself a lot of grief and reduce code size if you just capture the vector itself conditionally:
for (int i = 0; i < 2; i++) {
auto& vec = (i == 0 ? vec1 : vec2);
threads.push_back(
thread([&vec]() {
for (int j = 0; j < 10; j++) {
const string str = "foo";
vec.push_back(str);
}
})
);
}
Both for and the thread uses the same memory address of i (because you pass it by reference). Correct way is to let the thread have its own copy of i, which would be the same for the thread lifetime and independant from the loop changes.
I've decided to parallelize a huge program I wrote and eventually I came across the new C++11 smart pointers.
I had a routine that should be executed many times (usually above 1000 times) that is somewhat expensive. It was ran in a dead simple for loop, what I did was to install this for loop in a method which would be ran by some worker threads.
Did it so, made some parameters wrapped by a std::shared_ptr, cared for race conditions, everything seemed fine.
But now, some times, process will be aborted and I am given one of the following errors:
Process finished with exit code 139 (interrupted by signal 11:
SIGSEGV)
or
malloc.c:2395: sysmalloc: Assertion `(old_top == initial_top (av) &&
old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse
(old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
All of these errors occur while the parallel for is ongoing; not before, not right in the beginning, not in the end, but somewhere in between, which smells me like a race condition not covered.
The program is huge, but I created a miniature of it that is able to reproduce the problem:
#include <iostream>
#include <vector>
#include <unordered_map>
#include <thread>
#include <set>
#include <memory>
#include <atomic>
namespace std {
template <>
struct hash<std::multiset<unsigned long>>
{
std::size_t operator()(const std::multiset<unsigned long>& k) const
{
std::size_t r = 0;
bool shift = false;
for (auto&& it : k) {
r = (r >> !shift) ^ (std::hash<unsigned long>()(it) << shift);
shift = !shift;
}
return r;
}
};
}
typedef std::unordered_map<std::multiset<unsigned long>, int*> graphmap;
std::multiset<unsigned long>* bar(int pos) {
std::multiset<unsigned long> *label = new std::multiset<unsigned long>;
label->insert(pos%5);
label->insert(pos%2);
return label;
}
void foo(std::shared_ptr<graphmap> &kSubgraphs, int pos) {
int *v = (*kSubgraphs)[*bar(pos)];
if(v == nullptr) {
v = new int[pos+1]();
v[0]++;
} else {
v[pos]++;
}
}
void worker(std::shared_ptr<std::atomic_int> *counter, int n, std::shared_ptr<graphmap> *kSubgraphs)
{
for (int pos = (*counter)->fetch_add(1); pos <= n; pos = (*counter)->fetch_add(1)) {
if (pos%100==0) std::cout << pos << std::endl;
foo(*kSubgraphs, pos);
}
}
int main() {
int n = 1000;
std::vector<std::thread> threads;
std::shared_ptr<graphmap> kSubgraphs = std::make_shared<graphmap>();
std::shared_ptr<std::atomic_int> counter = std::make_shared<std::atomic_int>(0);
for (int i=0; i<5; i++) {
foo(kSubgraphs, n);
}
for (int i=0; i<4; i++) {
threads.push_back(std::thread(worker, &counter, n, &kSubgraphs));
}
for(auto& th : threads) th.join();
return 0;
}
This code basically mimics the behavior of the original code, which is to use an unordered_map keyed by a multiset with values that are pointers to int arrays. First some keys are inserted and the array initialized (maybe the problem is caused by the way I am initializing it?) and finally the worker threads run to update a unique position of the array of an entry of the unordered_map.
Two threads may access the same map entry simultaneously, but they will never write to the same index of the array at the same time.
Different from the original code, this code won't throw any errors when running over internet compilers such as ideone.com, I also tried to run it from CLion ide and no errors will occur (maybe it can occur errors if one tries enough times), but I got similar error as the original when running from the command line multiple times. I compiled it with:
g++ -std=c++11 -pthread -o test.exe test.cpp
And after running several times it eventually gives this error:
*** Error in `./test.exe': double free or corruption (fasttop): 0x00000000006a2d30 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x77725)[0x7fccc9d4f725]
/lib/x86_64-linux-gnu/libc.so.6(+0x7ff4a)[0x7fccc9d57f4a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7fccc9d5babc]
./test.exe[0x404e9e]
./test.exe[0x40431b]
./test.exe[0x4045ed]
./test.exe[0x407c6c]
./test.exe[0x4078d6]
./test.exe[0x40742a]
./test.exe[0x40869e]
./test.exe[0x4086be]
./test.exe[0x4085dd]
./test.exe[0x40842d]
./test.exe[0x4023a2]
./test.exe[0x401d55]
./test.exe[0x401c4a]
./test.exe[0x401c66]
./test.exe[0x401702]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7fccc9cf8830]
./test.exe[0x401199]
======= Memory map: ========
00400000-0040f000 r-xp 00000000 08:05 12202697 /home/rodrigo/test.exe
0060e000-0060f000 r--p 0000e000 08:05 12202697 /home/rodrigo/test.exe
0060f000-00610000 rw-p 0000f000 08:05 12202697 /home/rodrigo/test.exe
00691000-006c3000 rw-p 00000000 00:00 0 [heap]
7fcca8000000-7fcca8089000 rw-p 00000000 00:00 0
7fcca8089000-7fccac000000 ---p 00000000 00:00 0
7fccb0000000-7fccb008b000 rw-p 00000000 00:00 0
7fccb008b000-7fccb4000000 ---p 00000000 00:00 0
7fccb8000000-7fccb8089000 rw-p 00000000 00:00 0
7fccb8089000-7fccbc000000 ---p 00000000 00:00 0
7fccc0000000-7fccc007c000 rw-p 00000000 00:00 0
7fccc007c000-7fccc4000000 ---p 00000000 00:00 0
7fccc79cb000-7fccc79cc000 ---p 00000000 00:00 0
7fccc79cc000-7fccc81cc000 rw-p 00000000 00:00 0
7fccc81cc000-7fccc81cd000 ---p 00000000 00:00 0
7fccc81cd000-7fccc89cd000 rw-p 00000000 00:00 0
7fccc89cd000-7fccc89ce000 ---p 00000000 00:00 0
7fccc89ce000-7fccc91ce000 rw-p 00000000 00:00 0
7fccc91ce000-7fccc91cf000 ---p 00000000 00:00 0
7fccc91cf000-7fccc99cf000 rw-p 00000000 00:00 0
7fccc99cf000-7fccc9ad7000 r-xp 00000000 08:05 24126366 /lib/x86_64-linux-gnu/libm-2.23.so
7fccc9ad7000-7fccc9cd6000 ---p 00108000 08:05 24126366 /lib/x86_64-linux-gnu/libm-2.23.so
7fccc9cd6000-7fccc9cd7000 r--p 00107000 08:05 24126366 /lib/x86_64-linux-gnu/libm-2.23.so
7fccc9cd7000-7fccc9cd8000 rw-p 00108000 08:05 24126366 /lib/x86_64-linux-gnu/libm-2.23.so
7fccc9cd8000-7fccc9e98000 r-xp 00000000 08:05 24126374 /lib/x86_64-linux-gnu/libc-2.23.so
7fccc9e98000-7fccca097000 ---p 001c0000 08:05 24126374 /lib/x86_64-linux-gnu/libc-2.23.so
7fccca097000-7fccca09b000 r--p 001bf000 08:05 24126374 /lib/x86_64-linux-gnu/libc-2.23.so
7fccca09b000-7fccca09d000 rw-p 001c3000 08:05 24126374 /lib/x86_64-linux-gnu/libc-2.23.so
7fccca09d000-7fccca0a1000 rw-p 00000000 00:00 0
7fccca0a1000-7fccca0b9000 r-xp 00000000 08:05 24126373 /lib/x86_64-linux-gnu/libpthread-2.23.so
7fccca0b9000-7fccca2b8000 ---p 00018000 08:05 24126373 /lib/x86_64-linux-gnu/libpthread-2.23.so
7fccca2b8000-7fccca2b9000 r--p 00017000 08:05 24126373 /lib/x86_64-linux-gnu/libpthread-2.23.so
7fccca2b9000-7fccca2ba000 rw-p 00018000 08:05 24126373 /lib/x86_64-linux-gnu/libpthread-2.23.so
7fccca2ba000-7fccca2be000 rw-p 00000000 00:00 0
7fccca2be000-7fccca2d4000 r-xp 00000000 08:05 24121519 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fccca2d4000-7fccca4d3000 ---p 00016000 08:05 24121519 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fccca4d3000-7fccca4d4000 rw-p 00015000 08:05 24121519 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fccca4d4000-7fccca646000 r-xp 00000000 08:05 6029347 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fccca646000-7fccca846000 ---p 00172000 08:05 6029347 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fccca846000-7fccca850000 r--p 00172000 08:05 6029347 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fccca850000-7fccca852000 rw-p 0017c000 08:05 6029347 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fccca852000-7fccca856000 rw-p 00000000 00:00 0
7fccca856000-7fccca87c000 r-xp 00000000 08:05 24126370 /lib/x86_64-linux-gnu/ld-2.23.so
7fcccaa44000-7fcccaa4a000 rw-p 00000000 00:00 0
7fcccaa78000-7fcccaa7b000 rw-p 00000000 00:00 0
7fcccaa7b000-7fcccaa7c000 r--p 00025000 08:05 24126370 /lib/x86_64-linux-gnu/ld-2.23.so
7fcccaa7c000-7fcccaa7d000 rw-p 00026000 08:05 24126370 /lib/x86_64-linux-gnu/ld-2.23.so
7fcccaa7d000-7fcccaa7e000 rw-p 00000000 00:00 0
7ffc6b1c8000-7ffc6b1e9000 rw-p 00000000 00:00 0 [stack]
7ffc6b1fa000-7ffc6b1fc000 r--p 00000000 00:00 0 [vvar]
7ffc6b1fc000-7ffc6b1fe000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
[1] 26639 abort (core dumped) ./test.exe
At last, when running the original code with debug mode on in CLion set up to capture Exceptions as breakpoints, it shows a Signal interruption of SIGBUS(Bus error) or a SIGSEGV(Segmentation fault) sometimes and last line of code executed before the interruption maps to the line:
int *v = (*kSubgraphs)[*bar(pos)];
in the foo function of the code presented here.
I am a little bit lost with this one. My strongest assumption is that I am using smart pointers the wrong way, despite I do not see where.
Your program has undefined behavior, because you access the object pointed to by kSubgraphs from different threads without mutual exclusion. This happens in this line of code in function foo, which is called from your thread function worker:
int *v = (*kSubgraphs)[*bar(pos)];
I can't guess why you think shared_ptr would help your case in any way. The way you do, it is totally pointless to wrap your objects in shared_ptr.
shared_ptr is used when ownership of your objects is shared from different other objects. It has nothing to do with "sharing objects between threads".
I am trying to study the effect of pthread based Multi-threading code modifications on VIRTUAL memory on a 64-bit Centos based Linux system
I am attaching a spreadsheet where the observations were made on VIRTUAL MEMORY (using Linux based top command) with increasing the number of threads and each thread is allocating 1MB each.
I am pasting C++ code used for observation (below) for the reference:
From the observations made shown in the table below, for a single thread allocating 1MB data VIRTUAL memory used is 89.824MB, for 2 threads allocating 1MB each VIRTUAL memory is 165.604MB, for 3 threads allocating 1MB each VIRTUAL memory is 235MB and then onwards VIRTUAL memory increases by 1MB per thread.
Click here to view the table having observations made
To summarize, VIRTUAL memory starts with 89MB, becomes double after adding 2nd thread, again becomes almost double after adding 3rd thread, then increases by 1MB for addition of each thread, each allocating 1MB of heap.
Can anyone explain why is this behavior exhibited by the system ?
Please post if you need any other details. Looking forward for the help.
Note:
the code was compiled using g++ (g++ -o vma CODE_FILE.cpp -lpthread)
only 1MB of heap was allocated by each thread but were not populated
the generated binary size is only ~9KB (got using ls command)
#include <iostream>
#include <pthread.h>
using namespace std;
/*
NOTE: Make sure you provide NUM_THREADS in the range (1..5)
*/
#define NUM_THREADS 5
struct thread_struct
{
int id;
char *msg;
};
void *thrdFunc(void *i)
{
char *it = (char*)i;
cout << "\nthis is thread named :"<< it ;
char *mallocBlk = new char [1000000];
}
int main()
{
int rc = 0;
void *status;
char threadNames[8][8] = { "Thread1" , "Thread2", "Thread3", "Thread4", "Thread5", "Thread6", "Thread7", "Thread8"};
pthread_t threads[NUM_THREADS];
thread_struct thrStructs[NUM_THREADS];
cout << "\nIn Main, creating threads!" ;
/*
Create threads
*/
for (int i = 0; i < NUM_THREADS; i++)
{
rc = pthread_create(&threads[i], NULL, thrdFunc, &threadNames[i] );
if (rc)
{
cout << "Thrd" << i+1 << " cant be created";
}
}
/*
Wait till all the threads complete
*/
for (int i = 0; i < NUM_THREADS; i++)
{
pthread_join(threads[i], &status);
}
cout << endl;
cout << "Done! Waiting for your input!";
cin.get();
return 0;
}
Below is the memory map for 5 threads:
[rebaca#localhost stackoverflow]$ cat /proc/31528/maps
00400000-00401000 r-xp 00000000 fd:02 20451094 /home/rebaca/stackoverflow/vma
00601000-00602000 rw-p 00001000 fd:02 20451094 /home/rebaca/stackoverflow/vma
01784000-017a5000 rw-p 00000000 00:00 0 [heap]
305b400000-305b420000 r-xp 00000000 fd:00 1703944 /lib64/ld-2.12.so
305b61f000-305b620000 r--p 0001f000 fd:00 1703944 /lib64/ld-2.12.so
305b620000-305b621000 rw-p 00020000 fd:00 1703944 /lib64/ld-2.12.so
305b621000-305b622000 rw-p 00000000 00:00 0
305b800000-305b98a000 r-xp 00000000 fd:00 1703966 /lib64/libc-2.12.so
305b98a000-305bb8a000 ---p 0018a000 fd:00 1703966 /lib64/libc-2.12.so
305bb8a000-305bb8e000 r--p 0018a000 fd:00 1703966 /lib64/libc-2.12.so
305bb8e000-305bb90000 rw-p 0018e000 fd:00 1703966 /lib64/libc-2.12.so
305bb90000-305bb94000 rw-p 00000000 00:00 0
305bc00000-305bc17000 r-xp 00000000 fd:00 1703968 /lib64/libpthread-2.12.so
305bc17000-305be17000 ---p 00017000 fd:00 1703968 /lib64/libpthread-2.12.so
305be17000-305be18000 r--p 00017000 fd:00 1703968 /lib64/libpthread-2.12.so
305be18000-305be19000 rw-p 00018000 fd:00 1703968 /lib64/libpthread-2.12.so
305be19000-305be1d000 rw-p 00000000 00:00 0
305c800000-305c883000 r-xp 00000000 fd:00 1704110 /lib64/libm-2.12.so
305c883000-305ca82000 ---p 00083000 fd:00 1704110 /lib64/libm-2.12.so
305ca82000-305ca83000 r--p 00082000 fd:00 1704110 /lib64/libm-2.12.so
305ca83000-305ca84000 rw-p 00083000 fd:00 1704110 /lib64/libm-2.12.so
3066800000-3066816000 r-xp 00000000 fd:00 1704139 /lib64/libgcc_s-4.4.7-20120601.so.1
3066816000-3066a15000 ---p 00016000 fd:00 1704139 /lib64/libgcc_s-4.4.7-20120601.so.1
3066a15000-3066a16000 rw-p 00015000 fd:00 1704139 /lib64/libgcc_s-4.4.7-20120601.so.1
3066c00000-3066ce8000 r-xp 00000000 fd:00 809560 /usr/lib64/libstdc++.so.6.0.13
3066ce8000-3066ee8000 ---p 000e8000 fd:00 809560 /usr/lib64/libstdc++.so.6.0.13
3066ee8000-3066eef000 r--p 000e8000 fd:00 809560 /usr/lib64/libstdc++.so.6.0.13
3066eef000-3066ef1000 rw-p 000ef000 fd:00 809560 /usr/lib64/libstdc++.so.6.0.13
3066ef1000-3066f06000 rw-p 00000000 00:00 0
7fd3ec000000-7fd3ec115000 rw-p 00000000 00:00 0
7fd3ec115000-7fd3f0000000 ---p 00000000 00:00 0
7fd3f0000000-7fd3f0115000 rw-p 00000000 00:00 0
7fd3f0115000-7fd3f4000000 ---p 00000000 00:00 0
7fd3f4000000-7fd3f4115000 rw-p 00000000 00:00 0
7fd3f4115000-7fd3f8000000 ---p 00000000 00:00 0
7fd3f8000000-7fd3f8115000 rw-p 00000000 00:00 0
7fd3f8115000-7fd3fc000000 ---p 00000000 00:00 0
7fd3fc000000-7fd3fc115000 rw-p 00000000 00:00 0
7fd3fc115000-7fd400000000 ---p 00000000 00:00 0
7fd4032b6000-7fd4032b7000 ---p 00000000 00:00 0
7fd4032b7000-7fd403cb7000 rw-p 00000000 00:00 0
7fd403cb7000-7fd403cb8000 ---p 00000000 00:00 0
7fd403cb8000-7fd4046b8000 rw-p 00000000 00:00 0
7fd4046b8000-7fd4046b9000 ---p 00000000 00:00 0
7fd4046b9000-7fd4050b9000 rw-p 00000000 00:00 0
7fd4064bb000-7fd4064c1000 rw-p 00000000 00:00 0
7fd4064db000-7fd4064de000 rw-p 00000000 00:00 0
7ffc72456000-7ffc7246b000 rw-p 00000000 00:00 0 [stack]
7ffc72568000-7ffc72569000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
When I run a simple c++ program on my on Ubuntu system, I get double free or corruption error. This has been haunting me for a while now.
I have marked the line that gives me this error. When I comment that line, I get no error. How can I get rid of this error? Plz help!
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
int t;
int count = 0;
string a, b;
vector<int> v(57, 0);
cin >> t;
while(t--) {
cin >> a >> b;
for (int i = 0; i < a.size(); i++) {
v[a[i] - 65]++;
cout << char(a[i]) << " " << v[a[i] - 65] << endl;
}
cout << endl;
for (int j = 0; j < b.size(); j++) {
int id = b[j] - 65;
if (v[id] > 0) {
int abc = v[id];
v[id] = abc - 1; /*****ERROR******/
cout << char(b[j]) << " ";
count++;
}
}
cout << count << endl;
cout << "----" << endl;
count = 0;
}
return 0;
}
After enter the number of test cases and 2 string as input, I get the following error:
1
abcd
xyz
a 1
b 1
c 1
d 1
z 1
----
*** Error in `./a.out': double free or corruption (!prev): 0x09db6008 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x767e2)[0xb74b97e2]
/lib/i386-linux-gnu/libc.so.6(+0x77530)[0xb74ba530]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdlPv+0x1f)[0xb765db4f]
./a.out[0x8049147]
./a.out[0x8049091]
./a.out[0x8048f99]
./a.out[0x8048ef6]
./a.out[0x8048d79]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0xb745c935]
./a.out[0x80489a1]
======= Memory map: ========
08048000-0804a000 r-xp 00000000 08:05 4195506 /home/vijender/codechef/a.out
0804a000-0804b000 r--p 00001000 08:05 4195506 /home/vijender/codechef/a.out
0804b000-0804c000 rw-p 00002000 08:05 4195506 /home/vijender/codechef/a.out
09db6000-09dd7000 rw-p 00000000 00:00 0 [heap]
b73fe000-b7400000 rw-p 00000000 00:00 0
b7400000-b7441000 r-xp 00000000 08:05 3670121 /lib/i386-linux-gnu/libm-2.17.so
b7441000-b7442000 r--p 00040000 08:05 3670121 /lib/i386-linux-gnu/libm-2.17.so
b7442000-b7443000 rw-p 00041000 08:05 3670121 /lib/i386-linux-gnu/libm-2.17.so
b7443000-b75f1000 r-xp 00000000 08:05 3670122 /lib/i386-linux-gnu/libc-2.17.so
b75f1000-b75f3000 r--p 001ae000 08:05 3670122 /lib/i386-linux-gnu/libc-2.17.so
b75f3000-b75f4000 rw-p 001b0000 08:05 3670122 /lib/i386-linux-gnu/libc-2.17.so
b75f4000-b75f8000 rw-p 00000000 00:00 0
b75f8000-b7613000 r-xp 00000000 08:05 3670878 /lib/i386-linux-gnu/libgcc_s.so.1
b7613000-b7614000 r--p 0001a000 08:05 3670878 /lib/i386-linux-gnu/libgcc_s.so.1
b7614000-b7615000 rw-p 0001b000 08:05 3670878 /lib/i386-linux-gnu/libgcc_s.so.1
b7615000-b76f1000 r-xp 00000000 08:05 268046 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.17
b76f1000-b76f2000 ---p 000dc000 08:05 268046 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.17
b76f2000-b76f6000 r--p 000dc000 08:05 268046 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.17
b76f6000-b76f7000 rw-p 000e0000 08:05 268046 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.17
b76f7000-b76fe000 rw-p 00000000 00:00 0
b7717000-b771c000 rw-p 00000000 00:00 0
b771c000-b771d000 r-xp 00000000 00:00 0 [vdso]
b771d000-b773d000 r-xp 00000000 08:05 3670123 /lib/i386-linux-gnu/ld-2.17.so
b773d000-b773e000 r--p 0001f000 08:05 3670123 /lib/i386-linux-gnu/ld-2.17.so
b773e000-b773f000 rw-p 00020000 08:05 3670123 /lib/i386-linux-gnu/ld-2.17.so
bfa67000-bfa88000 rw-p 00000000 00:00 0 [stack]
Aborted (core dumped)
I believe the size of v is off by one; the biggest index you can get is 56, but 'z'-65 = 57. I'd recommend using an unordered_map instead of a vector, it also extends better to Unicode characters :).