This question already has answers here:
Is it smart to replace boost::thread and boost::mutex with c++11 equivalents?
(7 answers)
Closed 9 years ago.
have a code which used to run fine with boost thread under ubuntu. it's basic read only data sharing multithreading. I try to use C++11 instead of boost, very basic transition. the code compiles but have subtle bugs. crashes randomly with C++11 std thread. tried to use valgrind drd, but hard to read the debug info. Any thoughts?
==19608== Conflicting load by thread 3 at 0x00643be8 size 8
==19608== at 0x41CEBA: std::subtract_with_carry_engine<unsigned int, 24ul, 10ul, 24ul>::operator()() (random.tcc:601)
==19608== by 0x41CD6C: double std::generate_canonical<double, 53ul, std::subtract_with_carry_engine<unsigned int, 24ul, 10ul, 24ul> >(std::subtract_with_carry_engine<unsigned int, 24ul, 10ul, 24ul>&) (random.tcc:3475)
==19608== by 0x41CB06: std::__detail::_Adaptor<std::subtract_with_carry_engine<unsigned int, 24ul, 10ul, 24ul>, double>::operator()() (random.h:190)
==19608== by 0x41C877: double std::normal_distribution<double>::operator()<std::subtract_with_carry_engine<unsigned int, 24ul, 10ul, 24ul> >(std::subtract_with_carry_engine<unsigned int, 24ul, 10ul, 24ul>&, std::normal_distribution<double>::param_type const&) (random.tcc:1950)
==19608== by 0x41C688: double std::normal_distribution<double>::operator()<std::subtract_with_carry_engine<unsigned int, 24ul, 10ul, 24ul> >(std::subtract_with_carry_engine<unsigned int, 24ul, 10ul, 24ul>&) (random.h:2196)
==19608== by 0x41C379: nrand(double, double) (NRand.cpp:8)
==19608== by 0x416F78: ClassDef::set_x() (LoanDef.h:407)
==19608== by 0x4168CA: Sim(std::vector<ClassDef, std::allocator<ClassDef> >&, Assumption&, std::unordered_map<std::string, std::vector<double, std::allocator<double> >, std::hash<std::string>, std::equal_to<std::string>, std::allocator<std::pair<std::string const, std::vector<double, std::allocator<double> > > > >&, unsigned int, NextStepCalcML&, std::vector<std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >, std::allocator<std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > > >&, unsigned int, unsigned int) (NewSim.cpp:105)
==19608== by 0x411A09: _ZNSt12_Bind_simpleIFPFvRSt6vectorI7LoanDefSaIS1_EER10AssumptionRSt13unordered_mapISsS0_IdSaIdEESt4hashISsESt8equal_toISsESaISt4pairIKSsS9_EEEjR14NextStepCalcMLRS0_IS0_IS9_SaIS9_EESaISN_EEjjESt17reference_wrapperIS3_EST_IS5_EST_ISI_EjST_ISK_EST_ISP_EjjEE9_M_invokeIILm0ELm1ELm2ELm3ELm4ELm5ELm6ELm7EEEEvSt12_Index_tupleIIXspT_EEE (functional:1732)
==19608== by 0x4116AE: std::_Bind_simple<void (*()(std::reference_wrapper<std::vector<LoanDef, std::allocator<LoanDef> > >, std::reference_wrapper<Assumption>, std::reference_wrapper<std::unordered_map<std::string, std::vector<double, std::allocator<double> >, std::hash<std::string>, std::equal_to<std::string>, std::allocator<std::pair<std::string const, std::vector<double, std::allocator<double> > > > > >, unsigned int, std::reference_wrapper<NextStepCalcML>, std::reference_wrapper<std::vector<std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >, std::allocator<std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > > > >, unsigned int, unsigned int))(std::vector<LoanDef, std::allocator<ClassDef> >&, Assumption&, std::unordered_map<std::string, std::vector<double, std::allocator<double> >, std::hash<std::string>, std::equal_to<std::string>, std::allocator<std::pair<std::string const, std::vector<double, std::allocator<double> > > > >&, unsigned int, NextStep&, std::vector<std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >, std::allocator<std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > > >&, unsigned int, unsigned int)>::operator()() (functional:1720)
==19608== by 0x411647: std::thread::_Impl<std::_Bind_simple<void (*()(std::reference_wrapper<std::vector<ClassDef, std::allocator<ClassDef> > >, std::reference_wrapper<Assumption>, std::reference_wrapper<std::unordered_map<std::string, std::vector<double, std::allocator<double> >, std::hash<std::string>, std::equal_to<std::string>, std::allocator<std::pair<std::string const, std::vector<double, std::allocator<double> > > > > >, unsigned int, std::reference_wrapper<NextStep>, std::reference_wrapper<std::vector<std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >, std::allocator<std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > > > >, unsigned int, unsigned int))(std::vector<LoanDef, std::allocator<LoanDef> >&, Assumption&, std::unordered_map<std::string, std::vector<double, std::allocator<double> >, std::hash<std::string>, std::equal_to<std::string>, std::allocator<std::pair<std::string const, std::vector<double, std::allocator<double> > > > >&, unsigned int, NextStep&, std::vector<std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >, std::allocator<std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > > >&, unsigned int, unsigned int)> >::_M_run() (thread:115)
thank you. btw, I tried to use this random head file I wrote, not sure if it's safe under multithread environment. it used to work fine with boost.
myrand.hpp
#ifndef NRAND_H
#define NRAND_H
#include <random>
double nrand(double mean = 0., double sd = 1.);
double urand(double a=0., double b=0.);
#endif
and myrand.cpp
#include "NRand.h"
using namespace std;
double nrand(double mean, double sd) {
static random_device rd;
static subtract_with_carry_engine<unsigned,24,10,24> e(rd());
normal_distribution<> dist(mean, sd);
return dist(e);
}
double urand(double a, double b) {
static random_device rd;
static subtract_with_carry_engine<unsigned,24,10,24> e(rd());
uniform_real_distribution<> dist(a, b);
return dist(e);
}
many thanks.
IMHO, your code is not threadsafe and hence should not work correctly under C++11. I think the problem is that the static variables rd and e are global variables but not protected (by mutex), so concurrent calls will race.
Presumably, you can make this code threadsafe by making those variables thread_local, but I have no experience.
Related
I'm new to std::threads and I'm trying to figure out what I'm doing wrong.
The idea is having a static function inside a DataUtils class that splits the program in 10 threads, every of which will calculate "a part" of a convolution between two vectors.
For some reason it seems that the compiler can't assign the right function to the thread, but the arguments are correct.
Here is my code (I am sure there is a more elegant way to do this...)
void threadconv (std::vector<double> const &f, std::vector<double> const &g, std::vector<double> &out, int start, int stop,int nf,int ng){
for(auto i(start); i < stop; ++i) {
int const jmn = (i >= ng - 1)? i - (ng - 1) : 0;
int const jmx = (i < nf - 1)? i : nf - 1;
for(auto j(jmn); j <= jmx; ++j) {
out[i] += (f[j] * g[i - j]);
}
}
}
class DataUtils{
static std::vector<double> multiThreadedConvolution(std::vector<double> const &f, std::vector<double> const &g, int divide){
int const nf = f.size();
int const ng = g.size();
int const n = nf + ng - 1;
int i=0;
std::vector<double> out(n, double());
std::thread t1 (threadconv,f,g,out,0,divide,nf,ng);i++;
std::thread t2 (threadconv,f,g,out,divide*i,(divide*i)+divide,nf,ng);i++;
std::thread t3 (threadconv,f,g,out,divide*i,(divide*i)+divide,nf,ng);i++;
std::thread t4 (threadconv,f,g,out,divide*i,(divide*i)+divide, nf,ng);i++;
std::thread t5 (threadconv,f,g,out,divide*i,(divide*i)+divide, nf,ng);i++;
std::thread t6 (threadconv,f,g,out,divide*i,(divide*i)+divide, nf,ng);i++;
std::thread t7 (threadconv,f,g,out,divide*i,(divide*i)+divide, nf,ng);i++;
std::thread t8 (threadconv,f,g,out,divide*i,(divide*i)+divide, nf,ng);i++;
std::thread t9 (threadconv,f,g,out,divide*i,(divide*i)+divide, nf,ng);i++;
std::thread t10 (threadconv,f,g,out,divide*i,out.size(), nf,ng);
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
t6.join();
t7.join();
t8.join();
t9.join();
t10.join();
return out;
}
}
After trying to compile, this is the error message I receive:
/usr/include/c++/7/thread:240:2: error: no matching function for call to ‘std::thread::_Invoker<std::tuple<void (*)(const std::vector<double, std::allocator<double> >&, const std::vector<double, std::allocator<double> >&, std::vector<double, std::allocator<double> >&, int, int, int, int), std::vector<double, std::allocator<double> >, std::vector<double, std::allocator<double> >, std::vector<double, std::allocator<double> >, int, int, int, int> >::_M_invoke(std::thread::_Invoker<std::tuple<void (*)(const std::vector<double, std::allocator<double> >&, const std::vector<double, std::allocator<double> >&, std::vector<double, std::allocator<double> >&, int, int, int, int), std::vector<double, std::allocator<double> >, std::vector<double, std::allocator<double> >, std::vector<double, std::allocator<double> >, int, int, int, int> >::_Indices)’
operator()()
^~~~~~~~
/usr/include/c++/7/thread:231:4: note: candidate: template<long unsigned int ..._Ind> decltype (std::__invoke((_S_declval<_Ind>)()...)) std::thread::_Invoker<_Tuple>::_M_invoke(std::_Index_tuple<_Ind ...>) [with long unsigned int ..._Ind = {_Ind ...}; _Tuple = std::tuple<void (*)(const std::vector<double, std::allocator<double> >&, const std::vector<double, std::allocator<double> >&, std::vector<double, std::allocator<double> >&, int, int, int, int), std::vector<double, std::allocator<double> >, std::vector<double, std::allocator<double> >, std::vector<double, std::allocator<double> >, int, int, int, int>]
_M_invoke(_Index_tuple<_Ind...>)
^~~~~~~~~
/usr/include/c++/7/thread:231:4: note: template argument deduction/substitution failed:
/usr/include/c++/7/thread: In substitution of ‘template<long unsigned int ..._Ind> decltype (std::__invoke(_S_declval<_Ind>()...)) std::thread::_Invoker<std::tuple<void (*)(const std::vector<double, std::allocator<double> >&, const std::vector<double, std::allocator<double> >&, std::vector<double, std::allocator<double> >&, int, int, int, int), std::vector<double, std::allocator<double> >, std::vector<double, std::allocator<double> >, std::vector<double, std::allocator<double> >, int, int, int, int> >::_M_invoke<_Ind ...>(std::_Index_tuple<_Ind1 ...>) [with long unsigned int ..._Ind = {0, 1, 2, 3, 4, 5, 6, 7}]’:
/usr/include/c++/7/thread:240:2: required from ‘struct std::thread::_Invoker<std::tuple<void (*)(const std::vector<double, std::allocator<double> >&, const std::vector<double, std::allocator<double> >&, std::vector<double, std::allocator<double> >&, int, int, int, int), std::vector<double, std::allocator<double> >, std::vector<double, std::allocator<double> >, std::vector<double, std::allocator<double> >, int, int, int, int> >’
/usr/include/c++/7/thread:127:22: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(const std::vector<double>&, const std::vector<double>&, std::vector<double>&, int, int, int, int); _Args = {const std::vector<double, std::allocator<double> >&, const std::vector<double, std::allocator<double> >&, std::vector<double, std::allocator<double> >&, int, int&, const int&, const int&}]’
I used valgrind to check my project written in C++. It told me there was a definitely memory leak in a line with vector assignment.
What valgrind told is
==37533== 514,604 bytes in 124,984 blocks are definitely lost in loss record 369 of 433
==37533== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==37533== by 0x42BB89: __gnu_cxx::new_allocator<int>::allocate(unsigned long, void const*) (new_allocator.h:104)
==37533== by 0x42832B: std::allocator_traits<std::allocator<int> >::allocate(std::allocator<int>&, unsigned long) (alloc_traits.h:491)
==37533== by 0x424565: std::_Vector_base<int, std::allocator<int> >::_M_allocate(unsigned long) (stl_vector.h:170)
==37533== by 0x48B73F: int* std::vector<int, std::allocator<int> >::_M_allocate_and_copy<__gnu_cxx::__normal_iterator<int const*, std::vector<int, std::allocator<int> > > >(unsigned long, __gnu_cxx::__normal_iterator<int const*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int const*, std::vector<int, std::allocator<int> > >) (stl_vector.h:1224)
==37533== by 0x48B2BD: std::vector<int, std::allocator<int> >::operator=(std::vector<int, std::allocator<int> > const&) (vector.tcc:195)
==37533== by 0x603A49: Dict::DATrieT<unsigned short, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<int, std::allocator<int> > >::buildTrie(std::vector<Dict::DATrieT<unsigned short, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<int, std::allocator<int> > >::TermCode, std::allocator<Dict::DATrieT<unsigned short, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<int, std::allocator<int> > >::TermCode> > const&, std::vector<std::vector<Dict::DATrieT<unsigned short, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<int, std::allocator<int> > >::TrieNode, std::allocator<Dict::DATrieT<unsigned short, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<int, std::allocator<int> > >::TrieNode> >*, std::allocator<std::vector<Dict::DATrieT<unsigned short, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<int, std::allocator<int> > >::TrieNode, std::allocator<Dict::DATrieT<unsigned short, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<int, std::allocator<int> > >::TrieNode> >*> >&) (Datrie.cpp:467)
==37533== by 0x602758: Dict::DATrieT<unsigned short, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<int, std::allocator<int> > >::build(std::vector<Dict::DATrieT<unsigned short, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<int, std::allocator<int> > >::TermCode, std::allocator<Dict::DATrieT<unsigned short, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<int, std::allocator<int> > >::TermCode> > const&) (Datrie.cpp:178)
==37533== by 0x602103: Loader::Trie_Loader::InnerLoad(BaseDict_Collection&) (Trie_Loader.cpp:116)
==37533== by 0x473BA6: deduce::DeduceClassify::Get_Dat_EntityRec() (DeduceClassify.cpp:500)
==37533== by 0x470D7A: deduce::DeduceClassify::init(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<Qp_Dict> const&, Analyse::Analysis*, MINISEARCH::Index*, Normalization::Normalizer*) (DeduceClassify.cpp:53)
==37533== by 0x40E784: queryparser::CQueryParserImpl::Init(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (QueryParserImpl.cpp:120)
The code snippet is
if ((int) (*itVecIter)->code.size() == nLevel + 1)
{
treeNode.bEnd = true;
// NOTE: the memory leak happens at following
treeNode.weight = (*itVecIter)->weight;
itVecIter = vecIter.erase(itVecIter);
}
And the runtime callstack via gdb is
(gdb) bt
#0 Dict::DATrieT<unsigned short, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<int, std::allocator<int> > >::buildTrie (this=0x7fffffffd8f8, vkey_code=std::vector of length 125163, capacity 131072 = {...},
trie=std::vector of length 31422, capacity 31422 = {...}) at ./tools/Dict/Datrie.cpp:467
#1 0x0000000000602759 in Dict::DATrieT<unsigned short, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<int, std::allocator<int> > >::build (this=0x7fffffffd8f8, vkey_code=std::vector of length 125163, capacity 131072 = {...})
at ./tools/Dict/Datrie.cpp:178
#2 0x0000000000602104 in Loader::Trie_Loader::InnerLoad (this=0x7fffffffd8e0, dictPtrs=...) at loader//Trie_Loader.cpp:116
#3 0x0000000000473ba7 in deduce::DeduceClassify::Get_Dat_EntityRec (this=0xa2fb28) at Classification/Deduce//DeduceClassify.cpp:500
#4 0x0000000000470d7b in deduce::DeduceClassify::init (this=0xa2fb28, base_Path="..//data/",
qp_dict=std::shared_ptr (count 2, weak 0) 0x1bc14600, tokenizer=0xa2f998, indexer=0xf6efb0, pNormer=0xa2f898)
at Classification/Deduce//DeduceClassify.cpp:53
#5 0x000000000040e785 in queryparser::CQueryParserImpl::Init (this=0xa2f4a0, dataPath="../") at QueryParserImpl.cpp:120
#6 0x000000000043ca92 in main_process::test_main (argc=2, argv=0x7fffffffdd20) at MainProcess.cpp:284
#7 0x00000000006301ae in main (argc=3, argv=0x7fffffffde38) at main.cpp:57
I used template class in Datrie.cpp. And I am not sure why vector assignment with
treeNode.weight = (*itVecIter)->weight;
has memory leaks.
Thanks.
It seems that the assignment operator of treeNode.weight is called, it allocates some memory to use but never de-allocated.
==37533== by 0x48B73F: int* std::vector<int, std::allocator<int> >::_M_allocate_and_copy<__gnu_cxx::__normal_iterator<int const*, std::vector<int, std::allocator<int> > > >(unsigned long, __gnu_cxx::__normal_iterator<int const*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int const*, std::vector<int, std::allocator<int> > >) (stl_vector.h:1224)
==37533== by 0x48B2BD: std::vector<int, std::allocator<int> >::operator=(std::vector<int, std::allocator<int> > const&) (vector.tcc:195)
As #n.m.'s suggestion, I've checked the code whole around. And I think I found the issue. Simplified the class constructor/destructor and manipulation in following:
#include <iostream>
#include <vector>
#include <string.h>
using namespace std;
struct leak_struct {
vector<string> array;
int set;
};
int main(){
leak_struct ls;
ls.array.push_back("hello");
ls.array.push_back("world");
memset(&ls, 0, sizeof(ls));
ls.array.push_back("code");
ls.array.push_back("review");
memset(&ls, 0, sizeof(ls));
return 0;
}
The reason it leaks is at the line where memset is called, this call will nullify the vector pointer in struct and makes the new allocated buffer not freed.
I have written some C++ code that is structured as follows:
double kernel(params)
{
//code
}
void optimize(params)
{
//some code
double x = kernel();
//some more code
}
int main()
{
//some code
optimize();
//some more code
}
I tried profiling it with callgrind using the following commands:
g++ -O3 -g sgd.cpp
valgrind --tool=callgrind ./a.out commandline_args
callgrind_annotate callgrind.out.XXXX
I get the following output:
--------------------------------------------------------------------------------
Ir
--------------------------------------------------------------------------------
12,916,968,785 PROGRAM TOTALS
--------------------------------------------------------------------------------
Ir file:function
--------------------------------------------------------------------------------
5,862,783,191 /build/buildd/eglibc-2.15/string/../sysdeps/i386/i686/multiarch/memcpy-ssse3.S:__memmove_ssse3 [/lib/i386-linux-gnu/libc-2.15.so]
2,847,653,393 /build/buildd/eglibc-2.15/malloc/malloc.c:_int_malloc [/lib/i386-linux-gnu/libc-2.15.so]
1,327,109,692 /build/buildd/eglibc-2.15/malloc/malloc.c:_int_free [/lib/i386-linux-gnu/libc-2.15.so]
847,560,182 sgd.cpp:main [a.out]
503,022,767 /build/buildd/eglibc-2.15/malloc/malloc.c:malloc [/lib/i386-linux-gnu/libc-2.15.so]
235,458,068 /build/buildd/eglibc-2.15/malloc/malloc.c:free [/lib/i386-linux-gnu/libc-2.15.so]
213,580,120 /build/buildd/eglibc-2.15/math/../sysdeps/i386/fpu/e_exp.S:__ieee754_exp [/lib/i386-linux-gnu/libm-2.15.so]
203,349,602 ???:operator new(unsigned int) [/usr/lib/i386-linux-gnu/libstdc++.so.6.0.16]
192,222,108 /build/buildd/eglibc-2.15/math/../sysdeps/ieee754/dbl-64/w_exp.c:exp [/lib/i386-linux-gnu/libm-2.15.so]
128,438,068 /build/buildd/eglibc-2.15/string/../sysdeps/i386/i686/multiarch/strcat.S:0x0012ac73 [/lib/i386-linux-gnu/libc-2.15.so]
128,431,176 ???:operator delete(void*) [/usr/lib/i386-linux-gnu/libstdc++.so.6.0.16]
128,358,564 /usr/include/c++/4.6/ext/new_allocator.h:main
117,645,255 /usr/include/c++/4.6/bits/stl_vector.h:main
112,167,083 /usr/include/c++/4.6/bits/stl_algobase.h:main
Except main(), it doesn't show which parts of the source code take up most of the time. I know for a fact that most of the time is spent in optimize() function, and in turn a significant fraction of that time in kernel() function, but I can't see this from the output.
How do I go about getting the details so that I can speed up my code?
If it helps, I am using std::vectors extensively in the code. I had implemented a similar code some time back using arrays, and callgrind seemed to work fine then. Could this be an issue?
If I disable the O3 flag, I get the following output:
--------------------------------------------------------------------------------
Ir
--------------------------------------------------------------------------------
19,026,610,083 PROGRAM TOTALS
--------------------------------------------------------------------------------
Ir file:function
--------------------------------------------------------------------------------
5,233,252,577 /build/buildd/eglibc-2.15/string/../sysdeps/i386/i686/multiarch/memcpy-ssse3.S:__memmove_ssse3 [/lib/i386-linux-gnu/libc-2.15.so]
2,542,000,057 /build/buildd/eglibc-2.15/malloc/malloc.c:_int_malloc [/lib/i386-linux-gnu/libc-2.15.so]
1,184,626,252 /build/buildd/eglibc-2.15/malloc/malloc.c:_int_free [/lib/i386-linux-gnu/libc-2.15.so]
983,472,430 sgd.cpp:optimize(std::vector<double, std::allocator<double> >, std::vector<int, std::allocator<int> >, std::vector<double, std::allocator<double> >) [a.out]
781,018,740 ???:std::vector<double, std::allocator<double> >::operator[](unsigned int) [a.out]
772,117,839 sgd.cpp:kernel(std::vector<double, std::allocator<double> >, int, int, double) [a.out]
476,616,742 ???:std::vector<double, std::allocator<double> >::vector(std::vector<double, std::allocator<double> > const&) [a.out]
449,016,969 /build/buildd/eglibc-2.15/malloc/malloc.c:malloc [/lib/i386-linux-gnu/libc-2.15.so]
324,200,916 ???:std::vector<double, std::allocator<double> >::size() const [a.out]
305,705,504 ???:std::_Vector_base<double, std::allocator<double> >::_Vector_base(unsigned int, std::allocator<double> const&) [a.out]
267,492,204 ???:std::_Vector_base<double, std::allocator<double> >::~_Vector_base() [a.out]
238,309,873 /usr/include/c++/4.6/bits/stl_algobase.h:double* std::__copy_move<false, true, std::random_access_iterator_tag>::__copy_m<double>(double const*, double const*, double*) [a.out]
238,308,370 /usr/include/c++/4.6/bits/stl_algobase.h:double* std::__copy_move_a2<false, __gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, double*>(__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, __gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, double*) [a.out]
228,776,040 /usr/include/c++/4.6/bits/stl_algobase.h:std::_Miter_base<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > > >::iterator_type std::__miter_base<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > > >(__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >) [a.out]
228,776,038 /usr/include/c++/4.6/bits/stl_algobase.h:double* std::copy<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, double*>(__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, __gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, double*) [a.out]
210,178,748 /build/buildd/eglibc-2.15/malloc/malloc.c:free [/lib/i386-linux-gnu/libc-2.15.so]
210,172,446 ???:std::vector<double, std::allocator<double> >::~vector() [a.out]
209,711,018 sgd.cpp:square(double) [a.out]
190,646,380 /build/buildd/eglibc-2.15/math/../sysdeps/i386/fpu/e_exp.S:__ieee754_exp [/lib/i386-linux-gnu/libm-2.15.so]
181,517,469 ???:operator new(unsigned int) [/usr/lib/i386-linux-gnu/libstdc++.so.6.0.16]
171,582,030 /usr/include/c++/4.6/bits/stl_iterator_base_types.h:std::_Iter_base<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, true>::_S_base(__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >) [a.out]
171,581,742 /build/buildd/eglibc-2.15/math/../sysdeps/ieee754/dbl-64/w_exp.c:exp [/lib/i386-linux-gnu/libm-2.15.so]
152,853,344 ???:__gnu_cxx::new_allocator<double>::allocate(unsigned int, void const*) [a.out]
152,852,752 ???:std::_Vector_base<double, std::allocator<double> >::_Vector_impl::_Vector_impl(std::allocator<double> const&) [a.out]
152,517,360 /usr/include/c++/4.6/bits/stl_algobase.h:std::_Niter_base<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > > >::iterator_type std::__niter_base<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > > >(__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >) [a.out]
152,517,360 /usr/include/c++/4.6/bits/stl_iterator_base_types.h:std::_Iter_base<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, false>::_S_base(__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >) [a.out]
152,517,360 /usr/include/c++/4.6/bits/stl_iterator.h:__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >::__normal_iterator(double const* const&) [a.out]
133,746,571 ???:std::_Vector_base<double, std::allocator<double> >::_M_deallocate(double*, unsigned int) [a.out]
133,452,690 ???:std::vector<double, std::allocator<double> >::end() const [a.out]
133,452,690 ???:std::vector<double, std::allocator<double> >::begin() const [a.out]
131,134,604 sgd.cpp:sign(double) [a.out]
123,920,353 /usr/include/c++/4.6/bits/stl_algobase.h:double* std::__copy_move_a<false, double const*, double*>(double const*, double const*, double*) [a.out]
121,192,848 ???:std::vector<int, std::allocator<int> >::operator[](unsigned int) [a.out]
114,649,360 /build/buildd/eglibc-2.15/string/../sysdeps/i386/i686/multiarch/strcat.S:0x0012ac73 [/lib/i386-linux-gnu/libc-2.15.so]
114,642,456 ???:operator delete(void*) [/usr/lib/i386-linux-gnu/libstdc++.so.6.0.16]
114,388,018 /usr/include/c++/4.6/bits/stl_uninitialized.h:double* std::__uninitialized_copy<true>::__uninit_copy<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, double*>(__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, __gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, double*) [a.out]
114,388,018 /usr/include/c++/4.6/bits/stl_uninitialized.h:double* std::uninitialized_copy<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, double*>(__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, __gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, double*) [a.out]
114,388,018 /usr/include/c++/4.6/bits/stl_uninitialized.h:double* std::__uninitialized_copy_a<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, double*, double>(__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, __gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, double*, std::allocator<double>&) [a.out]
105,086,674 /usr/include/c++/4.6/bits/stl_vector.h:std::_Vector_base<double, std::allocator<double> >::_M_allocate(unsigned int) [a.out]
95,533,505 ???:std::_Vector_base<double, std::allocator<double> >::_M_get_Tp_allocator() [a.out]
95,533,300 /usr/include/c++/4.6/bits/stl_construct.h:void std::_Destroy<double*>(double*, double*) [a.out]
95,533,300 /usr/include/c++/4.6/bits/stl_construct.h:void std::_Destroy<double*, double>(double*, double*, std::allocator<double>&) [a.out]
95,532,970 /usr/include/c++/4.6/bits/allocator.h:std::allocator<double>::allocator(std::allocator<double> const&) [a.out]
95,323,350 /usr/include/c++/4.6/bits/stl_iterator.h:__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >::base() const [a.out]
76,594,040 /usr/include/c++/4.6/bits/allocator.h:std::allocator<double>::~allocator() [a.out]
76,428,152 /usr/include/c++/4.6/bits/stl_algobase.h:std::_Niter_base<double*>::iterator_type std::__niter_base<double*>(double*) [a.out]
76,426,584 /usr/include/c++/4.6/ext/new_allocator.h:__gnu_cxx::new_allocator<double>::deallocate(double*, unsigned int) [a.out]
76,426,344 ???:std::_Vector_base<double, std::allocator<double> >::_Vector_impl::~_Vector_impl() [a.out]
75,798,592 /usr/include/c++/4.6/bits/stl_algobase.h:__gnu_cxx::__enable_if<std::__is_scalar<double>::__value, double*>::__type std::__fill_n_a<double*, unsigned int, double>(double*, unsigned int, double const&) [a.out]
47,768,335 /usr/include/c++/4.6/bits/stl_iterator_base_types.h:std::_Iter_base<double*, false>::_S_base(double*) [a.out]
47,767,040 ???:__gnu_cxx::new_allocator<double>::max_size() const [a.out]
47,662,045 ???:std::_Vector_base<double, std::allocator<double> >::_M_get_Tp_allocator() const [a.out]
38,297,020 /usr/include/c++/4.6/ext/new_allocator.h:__gnu_cxx::new_allocator<double>::~new_allocator() [a.out]
This has more information than the previous output, but there are still two issues: One, output on unoptimized code doesn't help me make the optimized code faster. Two, most of the time (~50%) is taken up by libc functions, which I am not directly using in my code. How do I know which parts of the code map to these calls?
Recently other people upgraded our boost library, now I see this coredump when a read_json function is called heavily. Never seen this before. And I have #define BOOST_SPIRIT_THREADSAFE in the code, that's why this didn't happen before. Really need help!Thanks!
Program terminated with signal 11, Segmentation fault.
#0 0x00007f062ce0d094 in std::mem_fun1_t<int, boost::spirit::classic::impl::grammar_helper_base<boost::spirit::classic::grammar<boost::property_tree::json_parser::json_grammar<boost::property_tree::basic_ptree<std::string, std::string, std::less<std::string> > >, boost::spirit::classic::parser_context<boost::spirit::classic::nil_t> > >, boost::spirit::classic::grammar<boost::property_tree::json_parser::json_grammar<boost::property_tree::basic_ptree<std::string, std::string, std::less<std::string> > >, boost::spirit::classic::parser_context<boost::spirit::classic::nil_t> >*>::operator() (this=0x7f06120f4c90, __p=0x7f05f813faa0, __x=0x7f06120f4df0) at /usr/lib/gcc/x86_64-spcdn-linux-gnu/4.5.2/../../../../include/c++/4.5.2/bits/stl_function.h:605
in /usr/lib/gcc/x86_64-spcdn-linux-gnu/4.5.2/../../../../include/c++/4.5.2/bits/stl_function.h
#0 0x00007f062ce0d094 in std::mem_fun1_t<int, boost::spirit::classic::impl::grammar_helper_base<boost::spirit::classic::grammar<boost::property_tree::json_parser::json_grammar<boost::property_tree::basic_ptree<std::string, std::string, std::less<std::string> > >, boost::spirit::classic::parser_context<boost::spirit::classic::nil_t> > >, boost::spirit::classic::grammar<boost::property_tree::json_parser::json_grammar<boost::property_tree::basic_ptree<std::string, std::string, std::less<std::string> > >, boost::spirit::classic::parser_context<boost::spirit::classic::nil_t> >*>::operator() (this=0x7f06120f4c90, __p=0x7f05f813faa0, __x=0x7f06120f4df0) at /usr/lib/gcc/x86_64-spcdn-linux-gnu/4.5.2/../../../../include/c++/4.5.2/bits/stl_function.h:605
#1 0x00007f062ce0c66e in std::binder2nd<std::mem_fun1_t<int, boost::spirit::classic::impl::grammar_helper_base<boost::spirit::classic::grammar<boost::property_tree::json_parser::json_grammar<boost::property_tree::basic_ptree<std::string, std::string, std::less<std::string> > >, boost::spirit::classic::parser_context<boost::spirit::classic::nil_t> > >, boost::spirit::classic::grammar<boost::property_tree::json_parser::json_grammar<boost::property_tree::basic_ptree<std::string, std::string, std::less<std::string> > >, boost::spirit::classic::parser_context<boost::spirit::classic::nil_t> >*> >::operator() (this=0x7f06120f4c90, __x=#0x7f06001446e0) at /usr/lib/gcc/x86_64-spcdn-linux-gnu/4.5.2/../../../../include/c++/4.5.2/backward/binders.h:154
#2 0x00007f062ce0b87e in std::for_each<std::reverse_iterator<__gnu_cxx::__normal_iterator<boost::spirit::classic::impl::grammar_helper_base<boost::spirit::classic::grammar<boost::property_tree::json_parser::json_grammar<boost::property_tree::basic_ptree<std::string, std::string, std::less<std::string> > >, boost::spirit::classic::parser_context<boost::spirit::classic::nil_t> > >**, std::vector<boost::spirit::classic::impl::grammar_helper_base<boost::spirit::classic::grammar<boost::property_tree::json_parser::json_grammar<boost::property_tree::basic_ptree<std::string, std::string, std::less<std::string> > >, boost::spirit::classic::parser_context<boost::spirit::classic::nil_t> > >*, std::allocator<boost::spirit::classic::impl::grammar_helper_base<boost::spirit::classic::grammar<boost::property_tree::json_parser::json_grammar<boost::property_tree::basic_ptree<std::string, std::string, std::less<std::string> > >, boost::spirit::classic::parser_context<boost::spirit::classic::nil_t> > >*> > > >, std::binder2nd<std::mem_fun1_t<int, boost::spirit::classic::impl::grammar_helper_base<boost::spirit::classic::grammar<boost::property_tree::json_parser::json_grammar<boost::property_tree::basic_ptree<std::string, std::string, std::less<std::string> > >, boost::spirit::classic::parser_context<boost::spirit::classic::nil_t> > >, boost::spirit::classic::grammar<boost::property_tree::json_parser::json_grammar<boost::property_tree::basic_ptree<std::string, std::string, std::less<std::string> > >, boost::spirit::classic::parser_context<boost::spirit::classic::nil_t> >*> > > (__first=..., __last=..., __f=...) at /usr/lib/gcc/x86_64-spcdn-linux-gnu/4.5.2/../../../../include/c++/4.5.2/bits/stl_algo.h:4185
#3 0x00007f062ce0aa88 in boost::spirit::classic::impl::grammar_destruct<boost::spirit::classic::grammar<boost::property_tree::json_parser::json_grammar<boost::property_tree::basic_ptree<std::string, std::string, std::less<std::string> > >, boost::spirit::classic::parser_context<boost::spirit::classic::nil_t> > > (self=0x7f06120f4df0) at /usr/include/boost/spirit/home/classic/core/non_terminal/impl/grammar.ipp:324
#4 0x00007f062ce09c5f in boost::spirit::classic::grammar<boost::property_tree::json_parser::json_grammar<boost::property_tree::basic_ptree<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, boost::spirit::classic::parser_context<boost::spirit::classic::nil_t> >::~grammar (this=0x7f06120f4df0, __in_chrg=<optimized out>) at /usr/include/boost/spirit/home/classic/core/non_terminal/grammar.hpp:52
#5 0x00007f062ce093f7 in boost::property_tree::json_parser::json_grammar<boost::property_tree::basic_ptree<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::~json_grammar (this=0x7f06120f4df0, __in_chrg=<optimized out>) at /usr/include/boost/property_tree/detail/json_parser_read.hpp:162
#6 0x00007f062ce0987f in boost::property_tree::json_parser::read_json_internal<boost::property_tree::basic_ptree<std::string, std::string, std::less<std::string> > > (stream=..., pt=..., filename="") at /usr/include/boost/property_tree/detail/json_parser_read.hpp:310
#7 0x00007f062ce08eb6 in boost::property_tree::json_parser::read_json<boost::property_tree::basic_ptree<std::string, std::string, std::less<std::string> > > (stream=..., pt=...) at /usr/include/boost/property_tree/json_parser.hpp:45
Everywhere you include json_parser.hpp or Spirit, BOOST_SPIRIT_THREADSAFE must be defined. Defining it globally would be safest, in case another part of boost/yourApp uses Spirit without your knowledge.
For any inclusion where this isn't defined, Sprit annoyingly makes a static variable in grammar.ipp that'll be shared amongst all instances of Spirit. Your grammar_destruct error is because Spirit is missing this define in one of your modules.
I am trying to call the following C++ function from Fortran 90.
//Filename ctest.cpp
#include<iostream>
#include<vector>
extern "C"
{
extern struct{
std::vector< std::vector<double> > a;
std::vector< std::vector<double> > b;
std::vector< std::vector<double> > c;
}abc_;
}
int myfunc_(int y,int z)
{
std::vector< std::vector<double> > u(y,std::vector<double>(z,2.0));
std::vector< std::vector<double> > v(y,std::vector<double>(z,4.0));
std::vector< std::vector<double> > w(y,std::vector<double>(z,6.0));
abc_.a = u;
abc_.b = v;
abc_.c = w;
return(1);
}
The corresponding fortran code is
! File fortest.f90
! Fortran test code to interface with C++ code
! return struct from C++
program fortest
implicit none
common/abc/ a,b,c
double precision,dimension(10,10) :: a
double precision,dimension(10,10) :: b
double precision,dimension(10,10) :: c
integer y,z
y = 10
z = 10
call myfunc(y,z)
write(*,*) a,b,c
stop
end
Both codes compile without any problems individually. However, when I compile the 2 together to interface them, with
gfortran -o test fortest.o ctest.o
I get a really huge error message. I suspect the problem is with Fortran not recognizing C++ 2d std::vector. But I am enclosing the full message here in case anyone wants to have a look.
user#userpc$ gfortran -o test fortest.o ctest.o
fortest.o: In function `MAIN__':
fortest.f90:(.text+0x2d): undefined reference to `myfunc_'
ctest.o: In function `__static_initialization_and_destruction_0(int, int)':
ctest.cpp:(.text+0x379): undefined reference to `std::ios_base::Init::Init()'
ctest.cpp:(.text+0x37e): undefined reference to `std::ios_base::Init::~Init()'
ctest.o: In function `std::vector<double, std::allocator<double> >* std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >::_M_allocate_and_copy<__gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > > >(unsigned long, __gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >, __gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >)':
ctest.cpp:(.text._ZNSt6vectorIS_IdSaIdEESaIS1_EE20_M_allocate_and_copyIN9__gnu_cxx17__normal_iteratorIPKS1_S3_EEEEPS1_mT_SB_[std::vector<double, std::allocator<double> >* std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >::_M_allocate_and_copy<__gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > > >(unsigned long, __gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >, __gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >)]+0x62): undefined reference to `__cxa_end_catch'
ctest.cpp:(.text._ZNSt6vectorIS_IdSaIdEESaIS1_EE20_M_allocate_and_copyIN9__gnu_cxx17__normal_iteratorIPKS1_S3_EEEEPS1_mT_SB_[std::vector<double, std::allocator<double> >* std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >::_M_allocate_and_copy<__gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > > >(unsigned long, __gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >, __gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >)]+0x75): undefined reference to `__cxa_begin_catch'
ctest.cpp:(.text._ZNSt6vectorIS_IdSaIdEESaIS1_EE20_M_allocate_and_copyIN9__gnu_cxx17__normal_iteratorIPKS1_S3_EEEEPS1_mT_SB_[std::vector<double, std::allocator<double> >* std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >::_M_allocate_and_copy<__gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > > >(unsigned long, __gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >, __gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >)]+0x91): undefined reference to `__cxa_rethrow'
ctest.o: In function `__gnu_cxx::new_allocator<std::vector<double, std::allocator<double> > >::deallocate(std::vector<double, std::allocator<double> >*, unsigned long)':
ctest.cpp:(.text._ZN9__gnu_cxx13new_allocatorISt6vectorIdSaIdEEE10deallocateEPS3_m[__gnu_cxx::new_allocator<std::vector<double, std::allocator<double> > >::deallocate(std::vector<double, std::allocator<double> >*, unsigned long)]+0x1c): undefined reference to `operator delete(void*)'
ctest.o: In function `__gnu_cxx::new_allocator<double>::allocate(unsigned long, void const*)':
ctest.cpp:(.text._ZN9__gnu_cxx13new_allocatorIdE8allocateEmPKv[__gnu_cxx::new_allocator<double>::allocate(unsigned long, void const*)]+0x2c): undefined reference to `std::__throw_bad_alloc()'
ctest.cpp:(.text._ZN9__gnu_cxx13new_allocatorIdE8allocateEmPKv[__gnu_cxx::new_allocator<double>::allocate(unsigned long, void const*)]+0x3c): undefined reference to `operator new(unsigned long)'
ctest.o: In function `__gnu_cxx::new_allocator<double>::deallocate(double*, unsigned long)':
ctest.cpp:(.text._ZN9__gnu_cxx13new_allocatorIdE10deallocateEPdm[__gnu_cxx::new_allocator<double>::deallocate(double*, unsigned long)]+0x1c): undefined reference to `operator delete(void*)'
ctest.o: In function `__gnu_cxx::new_allocator<std::vector<double, std::allocator<double> > >::allocate(unsigned long, void const*)':
ctest.cpp:(.text._ZN9__gnu_cxx13new_allocatorISt6vectorIdSaIdEEE8allocateEmPKv[__gnu_cxx::new_allocator<std::vector<double, std::allocator<double> > >::allocate(unsigned long, void const*)]+0x2c): undefined reference to `std::__throw_bad_alloc()'
ctest.cpp:(.text._ZN9__gnu_cxx13new_allocatorISt6vectorIdSaIdEEE8allocateEmPKv[__gnu_cxx::new_allocator<std::vector<double, std::allocator<double> > >::allocate(unsigned long, void const*)]+0x45): undefined reference to `operator new(unsigned long)'
ctest.o: In function `std::vector<double, std::allocator<double> >* std::__uninitialized_copy<false>::__uninit_copy<std::vector<double, std::allocator<double> >*, std::vector<double, std::allocator<double> >*>(std::vector<double, std::allocator<double> >*, std::vector<double, std::allocator<double> >*, std::vector<double, std::allocator<double> >*)':
ctest.cpp:(.text._ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPSt6vectorIdSaIdEES5_EET0_T_S7_S6_[std::vector<double, std::allocator<double> >* std::__uninitialized_copy<false>::__uninit_copy<std::vector<double, std::allocator<double> >*, std::vector<double, std::allocator<double> >*>(std::vector<double, std::allocator<double> >*, std::vector<double, std::allocator<double> >*, std::vector<double, std::allocator<double> >*)]+0x62): undefined reference to `__cxa_end_catch'
ctest.cpp:(.text._ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPSt6vectorIdSaIdEES5_EET0_T_S7_S6_[std::vector<double, std::allocator<double> >* std::__uninitialized_copy<false>::__uninit_copy<std::vector<double, std::allocator<double> >*, std::vector<double, std::allocator<double> >*>(std::vector<double, std::allocator<double> >*, std::vector<double, std::allocator<double> >*, std::vector<double, std::allocator<double> >*)]+0x75): undefined reference to `__cxa_begin_catch'
ctest.cpp:(.text._ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPSt6vectorIdSaIdEES5_EET0_T_S7_S6_[std::vector<double, std::allocator<double> >* std::__uninitialized_copy<false>::__uninit_copy<std::vector<double, std::allocator<double> >*, std::vector<double, std::allocator<double> >*>(std::vector<double, std::allocator<double> >*, std::vector<double, std::allocator<double> >*, std::vector<double, std::allocator<double> >*)]+0x8d): undefined reference to `__cxa_rethrow'
ctest.o: In function `void std::__uninitialized_fill_n<false>::__uninit_fill_n<std::vector<double, std::allocator<double> >*, unsigned long, std::vector<double, std::allocator<double> > >(std::vector<double, std::allocator<double> >*, unsigned long, std::vector<double, std::allocator<double> > const&)':
ctest.cpp:(.text._ZNSt22__uninitialized_fill_nILb0EE15__uninit_fill_nIPSt6vectorIdSaIdEEmS4_EEvT_T0_RKT1_[void std::__uninitialized_fill_n<false>::__uninit_fill_n<std::vector<double, std::allocator<double> >*, unsigned long, std::vector<double, std::allocator<double> > >(std::vector<double, std::allocator<double> >*, unsigned long, std::vector<double, std::allocator<double> > const&)]+0x56): undefined reference to `__cxa_end_catch'
ctest.cpp:(.text._ZNSt22__uninitialized_fill_nILb0EE15__uninit_fill_nIPSt6vectorIdSaIdEEmS4_EEvT_T0_RKT1_[void std::__uninitialized_fill_n<false>::__uninit_fill_n<std::vector<double, std::allocator<double> >*, unsigned long, std::vector<double, std::allocator<double> > >(std::vector<double, std::allocator<double> >*, unsigned long, std::vector<double, std::allocator<double> > const&)]+0x69): undefined reference to `__cxa_begin_catch'
ctest.cpp:(.text._ZNSt22__uninitialized_fill_nILb0EE15__uninit_fill_nIPSt6vectorIdSaIdEEmS4_EEvT_T0_RKT1_[void std::__uninitialized_fill_n<false>::__uninit_fill_n<std::vector<double, std::allocator<double> >*, unsigned long, std::vector<double, std::allocator<double> > >(std::vector<double, std::allocator<double> >*, unsigned long, std::vector<double, std::allocator<double> > const&)]+0x81): undefined reference to `__cxa_rethrow'
ctest.o: In function `std::vector<double, std::allocator<double> >* std::__uninitialized_copy<false>::__uninit_copy<__gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >, std::vector<double, std::allocator<double> >*>(__gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >, __gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >, std::vector<double, std::allocator<double> >*)':
ctest.cpp:(.text._ZNSt20__uninitialized_copyILb0EE13__uninit_copyIN9__gnu_cxx17__normal_iteratorIPKSt6vectorIdSaIdEES4_IS6_SaIS6_EEEEPS6_EET0_T_SE_SD_[std::vector<double, std::allocator<double> >* std::__uninitialized_copy<false>::__uninit_copy<__gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >, std::vector<double, std::allocator<double> >*>(__gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >, __gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >, std::vector<double, std::allocator<double> >*)]+0x7c): undefined reference to `__cxa_end_catch'
ctest.cpp:(.text._ZNSt20__uninitialized_copyILb0EE13__uninit_copyIN9__gnu_cxx17__normal_iteratorIPKSt6vectorIdSaIdEES4_IS6_SaIS6_EEEEPS6_EET0_T_SE_SD_[std::vector<double, std::allocator<double> >* std::__uninitialized_copy<false>::__uninit_copy<__gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >, std::vector<double, std::allocator<double> >*>(__gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >, __gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >, std::vector<double, std::allocator<double> >*)]+0x8f): undefined reference to `__cxa_begin_catch'
ctest.cpp:(.text._ZNSt20__uninitialized_copyILb0EE13__uninit_copyIN9__gnu_cxx17__normal_iteratorIPKSt6vectorIdSaIdEES4_IS6_SaIS6_EEEEPS6_EET0_T_SE_SD_[std::vector<double, std::allocator<double> >* std::__uninitialized_copy<false>::__uninit_copy<__gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >, std::vector<double, std::allocator<double> >*>(__gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >, __gnu_cxx::__normal_iterator<std::vector<double, std::allocator<double> > const*, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >, std::vector<double, std::allocator<double> >*)]+0xa7): undefined reference to `__cxa_rethrow'
ctest.o: In function `double* std::vector<double, std::allocator<double> >::_M_allocate_and_copy<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > > >(unsigned long, __gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, __gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >)':
ctest.cpp:(.text._ZNSt6vectorIdSaIdEE20_M_allocate_and_copyIN9__gnu_cxx17__normal_iteratorIPKdS1_EEEEPdmT_S9_[double* std::vector<double, std::allocator<double> >::_M_allocate_and_copy<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > > >(unsigned long, __gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, __gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >)]+0x62): undefined reference to `__cxa_end_catch'
ctest.cpp:(.text._ZNSt6vectorIdSaIdEE20_M_allocate_and_copyIN9__gnu_cxx17__normal_iteratorIPKdS1_EEEEPdmT_S9_[double* std::vector<double, std::allocator<double> >::_M_allocate_and_copy<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > > >(unsigned long, __gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, __gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >)]+0x75): undefined reference to `__cxa_begin_catch'
ctest.cpp:(.text._ZNSt6vectorIdSaIdEE20_M_allocate_and_copyIN9__gnu_cxx17__normal_iteratorIPKdS1_EEEEPdmT_S9_[double* std::vector<double, std::allocator<double> >::_M_allocate_and_copy<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > > >(unsigned long, __gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, __gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >)]+0x91): undefined reference to `__cxa_rethrow'
ctest.o:(.eh_frame+0x6b): undefined reference to `__gxx_personality_v0'
collect2: ld returned 1 exit status
Any idea whats wrong.... in general terms how do I call multidimensional std::vectors from C++ in fortran? This will be of great use to people doing computational sciences.
std::vector is an object that can be expected to have various data members such as capacity, pointer-to-start-of-data, pointer-to-end etc.. The exact layout is not specified by the Standard - implementations may vary. The data is not stored directly in the vector - normally the pointer-to-start-of-data addresses heap-allocated memory. Therefore, you can't just point a fortran array at the vector object, as it will expect double data to be contiguously in memory from that address. You can't even use the .data() member to get the address where the pointer points, as in your case that's another vector and has the same problem. Put another way, your data just isn't contiguous in memory so won't correspond to the memory layout for a 2-dimensional array.
You could try copying the data into a packed two-dimensional array: if you know the dimensions will always be 10x10, then you can use a stack allocated area such as double data[10][10], otherwise you can double* p = new double[100] and put the logical value for [x][y] into element [x*10+y]. I'm guessing that's what your fortran implementation will expect but don't know for sure. It could be that it will expect contiguous data but packs it using [x+10*y], or it's even possible that it might introduce some other padding. It's worth checking with your fortran documentation. If all else fails (or you just think it's fun) you should be able to work it out by putting data into the fortran array and looking at the memory in a debugger to work out the layout.