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.
Related
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 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.
I just have a 10 line c++ program and it throws a half page error when I run it.
This is the following program
void getDataset(double ** f, int nRows, int nAttribute){
ifstream u;
u.open("iris.txt");
for(int i = 0; i < nRows; i++)
for(int j = 0; j < nAttribute; j++)
u >> f[i][j];
}
int main(){
int nRows = 150, nAttribute = 4, k = 3;
double * mat[nRows];
for(int i = 0; i < nRows; i++){
mat[i] = new double(nAttribute);
}
mat[149][3] = 2;
getDataset(mat, nRows, nAttribute);
cout << mat[100][2] << endl;
}
I tried to copy the error using ./a.out > error.log but its not working. The error.log is empty. So I had to copy paste it here, directly.
*** glibc detected *** ./a.out: free(): invalid next size (fast): 0x0000000000ef1520 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7e846)[0x7f8ba675b846]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZNSsD1Ev+0x23)[0x7f8ba704cc13]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRd+0xf5)[0x7f8ba703cb25]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZNSi10_M_extractIdEERSiRT_+0x8f)[0x7f8ba702d22f]
./a.out[0x40170c]
./a.out[0x40186f]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7f8ba66fe76d]
./a.out[0x400aa9]
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:06 524669 /home/aditya/Documents/a.out
00601000-00602000 r--p 00001000 08:06 524669 /home/aditya/Documents/a.out
00602000-00603000 rw-p 00002000 08:06 524669 /home/aditya/Documents/a.out
00eee000-00f0f000 rw-p 00000000 00:00 0 [heap]
7f8ba66dd000-7f8ba6892000 r-xp 00000000 08:06 1447163 /lib/x86_64-linux-gnu/libc-2.15.so
7f8ba6892000-7f8ba6a91000 ---p 001b5000 08:06 1447163 /lib/x86_64-linux-gnu/libc-2.15.so
7f8ba6a91000-7f8ba6a95000 r--p 001b4000 08:06 1447163 /lib/x86_64-linux-gnu/libc-2.15.so
7f8ba6a95000-7f8ba6a97000 rw-p 001b8000 08:06 1447163 /lib/x86_64-linux-gnu/libc-2.15.so
7f8ba6a97000-7f8ba6a9c000 rw-p 00000000 00:00 0
7f8ba6a9c000-7f8ba6ab1000 r-xp 00000000 08:06 1440108 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f8ba6ab1000-7f8ba6cb0000 ---p 00015000 08:06 1440108 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f8ba6cb0000-7f8ba6cb1000 r--p 00014000 08:06 1440108 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f8ba6cb1000-7f8ba6cb2000 rw-p 00015000 08:06 1440108 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f8ba6cb2000-7f8ba6dad000 r-xp 00000000 08:06 1447283 /lib/x86_64-linux-gnu/libm-2.15.so
7f8ba6dad000-7f8ba6fac000 ---p 000fb000 08:06 1447283 /lib/x86_64-linux-gnu/libm-2.15.so
7f8ba6fac000-7f8ba6fad000 r--p 000fa000 08:06 1447283 /lib/x86_64-linux-gnu/libm-2.15.so
7f8ba6fad000-7f8ba6fae000 rw-p 000fb000 08:06 1447283 /lib/x86_64-linux-gnu/libm-2.15.so
7f8ba6fae000-7f8ba7090000 r-xp 00000000 08:06 400528 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7f8ba7090000-7f8ba728f000 ---p 000e2000 08:06 400528 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7f8ba728f000-7f8ba7297000 r--p 000e1000 08:06 400528 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7f8ba7297000-7f8ba7299000 rw-p 000e9000 08:06 400528 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7f8ba7299000-7f8ba72ae000 rw-p 00000000 00:00 0
7f8ba72ae000-7f8ba72d0000 r-xp 00000000 08:06 1447286 /lib/x86_64-linux-gnu/ld-2.15.so
7f8ba74b3000-7f8ba74b8000 rw-p 00000000 00:00 0
7f8ba74cd000-7f8ba74d0000 rw-p 00000000 00:00 0
7f8ba74d0000-7f8ba74d1000 r--p 00022000 08:06 1447286 /lib/x86_64-linux-gnu/ld-2.15.so
7f8ba74d1000-7f8ba74d3000 rw-p 00023000 08:06 1447286 /lib/x86_64-linux-gnu/ld-2.15.so
7fff6ef55000-7fff6ef76000 rw-p 00000000 00:00 0 [stack]
7fff6ef8c000-7fff6ef8d000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted
You are not allocating a double array with new double(nAttribute). Your code needs to change to new double[ nAttribute ].
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 :).
So I have an array of n streams that I open with pipes, but using gdb, I found that the program fails when I try to close either the stream or the write end of the pipes. I can write to the pipes just fine, but closing them doesn't work. I ran valgrind on the program and all it did was print out
==4241== Warning: invalid file descriptor -1 in syscall read()
over and over again. Here is the code in question and error output. If any more info is needed please let me know and I will try to provide it. Thanks everyone.
191 /*closes unused pipes and open streams to sorting processes*/
192 for (i = 0; i < n; i++) {
193 close(parse2sortPipes[i][READ]);
194 close(sort2outputPipes[i][READ]);
195 close(sort2outputPipes[i][WRITE]);
196 outStreams[i] = fdopen(parse2sortPipes[i][WRITE], "w");
197 }
198
199 while (getWord(fstream, wBuf) != -1) {
200 if (i == n) {
201 i = 0;
202 }
203 fputs(wBuf, outStreams[i]);
204 fputc('\n', outStreams[i]);
205 i++;
206 }
207
208
209
210 for (i = 0; i < n; i++) {
211 fflush(outStreams[i]);
212 fclose(outStreams[i]); //this is where it fails
213 close(parse2sortPipes[i][WRITE]);
214 }
215
*** Error in `..../xxx': double free or corruption (top): 0x0000000000603250 ***
======= Backtrace: =========
208 for (i = 0; i < n; i++) {
/lib/x86_64-linux-gnu/libc.so.6(+0x80a46)[0x7ffff7a92a46]
/lib/x86_64-linux-gnu/libc.so.6(fclose+0x14d)[0x7ffff7a80a6d]
/home/user/school/cs/assignments/hw3/xxx[0x401477]
/home/user/school/cs/assignments/hw3/xxx[0x400ce7]
(gdb) /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0x7ffff7a33ea5]
/home/user/school/cs/assignments/hw3/xxx[0x400b39]
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:06 12588471 /home/daniel/school/cs311/assignments/hw3/xxx
00601000-00602000 r--p 00001000 08:06 12588471 /home/daniel/school/cs311/assignments/hw3/xxx
00602000-00603000 rw-p 00002000 08:06 12588471 /home/daniel/school/cs311/assignments/hw3/xxx
00603000-00624000 rw-p 00000000 00:00 0 [heap]
7ffff77fc000-7ffff7810000 r-xp 00000000 08:06 3149442 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff7810000-7ffff7a10000 ---p 00014000 08:06 3149442 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff7a10000-7ffff7a11000 r--p 00014000 08:06 3149442 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff7a11000-7ffff7a12000 rw-p 00015000 08:06 3149442 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff7a12000-7ffff7bd0000 r-xp 00000000 08:06 3149417 /lib/x86_64-linux-gnu/libc-2.17.so
7ffff7bd0000-7ffff7dcf000 ---p 001be000 08:06 3149417 /lib/x86_64-linux-gnu/libc-2.17.so
7ffff7dcf000-7ffff7dd3000 r--p 001bd000 08:06 3149417 /lib/x86_64-linux-gnu/libc-2.17.so
7ffff7dd3000-7ffff7dd5000 rw-p 001c1000 08:06 3149417 /lib/x86_64-linux-gnu/libc-2.17.so
7ffff7dd5000-7ffff7dda000 rw-p 00000000 00:00 0
7ffff7dda000-7ffff7dfd000 r-xp 00000000 08:06 3149393 /lib/x86_64-linux-gnu/ld-2.17.so
7ffff7fd7000-7ffff7fda000 rw-p 00000000 00:00 0
7ffff7ff6000-7ffff7ff8000 rw-p 00000000 00:00 0
7ffff7ff8000-7ffff7ffa000 rw-p 00000000 00:00 0
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00022000 08:06 3149393 /lib/x86_64-linux-gnu/ld-2.17.so
7ffff7ffd000-7ffff7fff000 rw-p 00023000 08:06 3149393 /lib/x86_64-linux-gnu/ld-2.17.so
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
fclose will close the underlying file descriptor, so don't call close afterwards.