AddSymbolicGradients is failing on recursive implementation - c++

I'm implementing a simple RNN with the Tensorflow C++ APIs.
Currently using the 1.13 from github.
The call to AddSymbolicGradients (last line) fails into a Segmentation fault.
gdb teels me that the error occurs inside SymbolicGradientBuilder::Initialize
auto input_slices = Split(scope, 1, x, window_size);
auto initial_state = Fill(scope, {batch_size, state_size}, 0);
vector<Output> states;
states.reserve(window_size+1);
states.push_back(initial_state);
for (int i=0; i!=window_size; i++) {
auto concat = Concat(scope, InputList(initializer_list<Input>{input_slices[i], states[i]}), 1);
auto new_state = Tanh(scope, Add(scope, MatMul(scope, concat, w_rnn), b_rnn));
states.push_back(new_state);
}
// dense output
auto out = Tanh(scope, Add(scope, MatMul(scope, states[window_size], w_dense), b_dense));
// loss function
auto loss = ReduceMean(scope, Square(scope, Sub(scope, out, y)), {0, 1});
vector<Output> grad_outputs;
TF_CHECK_OK(AddSymbolicGradients(scope, {loss}, {w_rnn, w_dense, b_rnn, b_dense}, &grad_outputs));
Any idea? Thanks
EDIT: gdb where full output
(gdb) where
#0 0x00005555559b45aa in tensorflow::(anonymous namespace)::SymbolicGradientBuilder::Initialize() ()
#1 0x00005555559b6f1c in tensorflow::AddSymbolicGradients(tensorflow::Scope const&, std::vector<tensorflow::Output, std::allocator<tensorflow::O
utput> > const&, std::vector<tensorflow::Output, std::allocator<tensorflow::Output> > const&, std::vector<tensorflow::Output, std::allocator<tens
orflow::Output> > const&, std::vector<tensorflow::Output, std::allocator<tensorflow::Output> >*) ()
#2 0x00005555559b9bb2 in tensorflow::AddSymbolicGradients(tensorflow::Scope const&, std::vector<tensorflow::Output, std::allocator<tensorflow::O
utput> > const&, std::vector<tensorflow::Output, std::allocator<tensorflow::Output> > const&, std::vector<tensorflow::Output, std::allocator<tens
orflow::Output> >*) ()
#3 0x000055555597ce6c in Rnn::train(Dataset, int, int, int) ()
#4 0x00005555558410d6 in main ()

Related

How can i fix Onnxruntime session->Run problem?

I am trying to write a wrapper for onnxruntime.
The model receives one tensor as an input and one tensor as an output.
During session->Run, a segmentation error occurs inside the onnxruntime library. Both downloaded library and built from source throw the same error.
Here is error:
Thread 1 "app" received signal SIGSEGV, Segmentation fault.
0x00007ffff6b16eb1 in onnxruntime::logging::ISink::Send (this=0x5555559154c0, timestamp=..., logger_id="", message=...) at /home/listray/Work/Libs/onnxruntime/include/onnxruntime/core/common/logging/isink.h:23
23 SendImpl(timestamp, logger_id, message);
Here is bt:
#0 0x00007ffff6b16eb1 in onnxruntime::logging::ISink::Send (this=0x5555559154c0, timestamp=..., logger_id="", message=...)
at /home/listray/Work/Libs/onnxruntime/include/onnxruntime/core/common/logging/isink.h:23
#1 0x00007ffff6b174b8 in onnxruntime::logging::LoggingManager::Log (this=0x55555576cbb0, logger_id="", message=...) at /home/listray/Work/Libs/onnxruntime/onnxruntime/core/common/logging/logging.cc:153
#2 0x00007ffff6b16cae in onnxruntime::logging::Logger::Log (this=0x7fffffffcdd0, message=...) at /home/listray/Work/Libs/onnxruntime/include/onnxruntime/core/common/logging/logging.h:291
#3 0x00007ffff6b16ce0 in onnxruntime::logging::Capture::~Capture (this=0x7fffffffc4e0, __in_chrg=<optimized out>) at /home/listray/Work/Libs/onnxruntime/onnxruntime/core/common/logging/capture.cc:57
#4 0x00007ffff6a86301 in onnxruntime::SequentialExecutor::Execute(onnxruntime::SessionState const&, std::vector<int, std::allocator<int> > const&, std::vector<OrtValue, std::allocator<OrtValue> > const&, std::vector<int, std::allocator<int> > const&, std::vector<OrtValue, std::allocator<OrtValue> >&, std::unordered_map<unsigned long, std::function<onnxruntime::common::Status (onnxruntime::TensorShape const&, OrtMemoryInfo const&, OrtValue&, bool&)>, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<std::pair<unsigned long const, std::function<onnxruntime::common::Status (onnxruntime::TensorShape const&, OrtMemoryInfo const&, OrtValue&, bool&)> > > > const&, onnxruntime::logging::Logger const&) (this=0x5555559da4c0, session_state=..., feed_mlvalue_idxs=std::vector of length 1, capacity 1 = {...},
feeds=std::vector of length 1, capacity 1 = {...}, fetch_mlvalue_idxs=std::vector of length 1, capacity 1 = {...}, fetches=std::vector of length 1, capacity 1 = {...},
fetch_allocators=std::unordered_map with 0 elements, logger=...) at /home/listray/Work/Libs/onnxruntime/onnxruntime/core/framework/sequential_executor.cc:309
#5 0x00007ffff6a6d787 in onnxruntime::utils::ExecuteGraphImpl(const onnxruntime::SessionState &, const onnxruntime::FeedsFetchesManager &, const std::vector<OrtValue, std::allocator<OrtValue> > &, std::vector<OrtValue, std::allocator<OrtValue> > &, const std::unordered_map<long unsigned int, std::function<onnxruntime::common::Status(const onnxruntime::TensorShape&, const OrtMemoryInfo&, OrtValue&, bool&)>, std::hash<long unsigned int>, std::equal_to<long unsigned int>, std::allocator<std::pair<long unsigned int const, std::function<onnxruntime::common::Status(const onnxruntime::TensorShape&, const OrtMemoryInfo&, OrtValue&, bool&)> > > > &, ExecutionMode, const bool &, const onnxruntime::logging::Logger &, bool) (session_state=..., feeds_fetches_manager=..., feeds=std::vector of length 1, capacity 1 = {...},
fetches=std::vector of length 1, capacity 1 = {...}, fetch_allocators=std::unordered_map with 0 elements, execution_mode=ORT_SEQUENTIAL, terminate_flag=#0x7fffffffd168: false, logger=...,
only_execute_path_to_fetches=false) at /home/listray/Work/Libs/onnxruntime/onnxruntime/core/framework/utils.cc:454
#6 0x00007ffff6a6df37 in onnxruntime::utils::ExecuteGraph (session_state=..., feeds_fetches_manager=..., feeds=std::vector of length 1, capacity 1 = {...}, fetches=std::vector of length 1, capacity 1 = {...},
execution_mode=ORT_SEQUENTIAL, terminate_flag=#0x7fffffffd168: false, logger=..., only_execute_path_to_fetches=false) at /home/listray/Work/Libs/onnxruntime/onnxruntime/core/framework/utils.cc:513
#7 0x00007ffff63e00c2 in onnxruntime::InferenceSession::Run (this=0x555555917110, run_options=..., feed_names=std::vector of length 1, capacity 1 = {...}, feeds=std::vector of length 1, capacity 1 = {...},
output_names=std::vector of length 1, capacity 1 = {...}, p_fetches=0x7fffffffd120) at /home/listray/Work/Libs/onnxruntime/onnxruntime/core/session/inference_session.cc:1206
#8 0x00007ffff637ecc3 in OrtApis::Run (sess=0x555555917110, run_options=0x0, input_names=0x5555559c1a10, input=0x7fffffffd2f8, input_len=1, output_names1=0x555555a521a0, output_names_len=1,
output=0x555555a3fb30) at /home/listray/Work/Libs/onnxruntime/onnxruntime/core/session/onnxruntime_c_api.cc:506
#9 0x00007ffff7ba6a93 in Ort::Session::Run (this=0x555555916440, run_options=..., input_names=0x5555559c1a10, input_values=0x7fffffffd2f8, input_count=1, output_names=0x555555a521a0,
output_values=0x555555a3fb30, output_count=1) at /home/listray/Work/Libs/onnx_debug/include/onnxruntime_cxx_inline.h:246
#10 0x00007ffff7ba69da in Ort::Session::Run (this=0x555555916440, run_options=..., input_names=0x5555559c1a10, input_values=0x7fffffffd2f8, input_count=1, output_names=0x555555a521a0, output_names_count=1)
at /home/listray/Work/Libs/onnx_debug/include/onnxruntime_cxx_inline.h:237
#11 0x00007ffff7bb0b31 in ai::common::OnnxruntimeGenericModelWrapper<1ul, 1ul>::process (this=0x55555576cb60, tensors=...)
at /home/listray/Work/Projects/ml-library/framework/onnxruntime/onnx_generic_model_wrapper.h:48
...
The downloaded library stops at onnxruntime::logging::LoggingManager::Log.
Here is some wrapper code.
Loading the model:
void load_graph(const ByteBuffer& model)
{
// enviroment maintains thread pools and other state info
Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "Vicue Run");
// initialize session options
Ort::SessionOptions session_options(nullptr);
//session_options.SetIntraOpNumThreads(1);
//Loading models
session = std::make_unique<Ort::Session>(env,
static_cast<const void*>(model.data.get()),
model.length,
session_options);
}
session is wrapper's field:
std::unique_ptr<Ort::Session> session;
ByteBuffer:
struct ByteBuffer
{
std::unique_ptr<char[]> data;
size_t length;
}
Actually wrapper was generic, but this code gets the same error.
std::array<Tensor, outputs> process(std::array<Tensor, inputs> tensors) override
{
std::array<Tensor, outputs> result;
// maybe this should be different if we have multiple input
Ort::AllocatorWithDefaultOptions allocator;
auto memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
if(outputs == 1 && inputs == 1) {
auto input_shape = session->GetInputTypeInfo(0).GetTensorTypeAndShapeInfo().GetShape();
Ort::Value input_tensor = Ort::Value::CreateTensor<float>(memory_info,
tensors[0].data.data(),
tensors[0].data.size(),
input_shape.data(),
input_shape.size());
std::vector<const char*> input_node_names = { session->GetInputName(0, allocator) };
std::vector<const char*> output_node_names = { session->GetOutputName(0, allocator) };
std::vector<Ort::Value> output_tensors = session->Run(Ort::RunOptions{nullptr},
input_node_names.data(),
&input_tensor,
inputs,
output_node_names.data(),
outputs);
One strange thing that I don't understand. During an error i see this:
(gdb) print this
$4 = (onnxruntime::logging::Capture * const) 0x7fffffffc4e0
(gdb) print this->logger_->logging_manager_->sink_
$5 = std::unique_ptr<onnxruntime::logging::ISink> = {get() = 0x5555559154c0}
(gdb) print *(this->logger_->logging_manager_->sink_)
$6 = {_vptr.ISink = 0x0}
When the logger is created, its *(logging_manager_->sink_) is also {_vptr.ISink = 0x0}.
I do not have the complete idea of your code structure but try making Ort::Env variable static.

eraseFromParent() Error

I'm trying to delete some instructions in IR. For analysis purpose, these instructions are inserted before, and now I need to delete them.
BasicBlock::reverse_iterator I = (*b).rbegin();
BasicBlock::reverse_iterator Ie = (*b).rend();
int i=0;
for ( ; I != Ie;I++)
{
if(i>0&&i<4){
errs()<<" Instruction "<<*I<<"\n";
I->eraseFromParent();
i++;
}
else{
i++;
}
}
This code is used in Transformation pass. When I run it, the output error are:
#0 0x00000000032bff15 (opt+0x32bff15)
#1 0x00000000032bffa6 (opt+0x32bffa6)
#2 0x00000000032be43e (opt+0x32be43e)
#3 0x00000000032bf8ac (opt+0x32bf8ac)
#4 0x00007f26cfa81330 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x10330)
#5 0x00007f26ce81a89a llvm::PointerIntPair<llvm::ilist_node_base<true>*, 1u, unsigned int, llvm::PointerLikeTypeTraits<llvm::ilist_node_base<true>*>, llvm::PointerIntPairInfo<llvm::ilist_node_base<true>*, 1u, llvm::PointerLikeTypeTraits<llvm::ilist_node_base<true>*> > >::getInt() const /home/rasha/llvm/llvm/include/llvm/ADT/PointerIntPair.h:59:0
#6 0x00007f26ce813516 llvm::ilist_node_base<true>::isSentinel() const /home/rasha/llvm/llvm/include/llvm/ADT/ilist_node_base.h:46:0
#7 0x00007f26ce813536 llvm::ilist_node_base<true>::isKnownSentinel() const /home/rasha/llvm/llvm/include/llvm/ADT/ilist_node_base.h:47:0
#8 0x00007f 26ce81e1d9 llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Instruction, true, false, void>, true, false>::operator*() const /home/rasha/llvm/llvm/include/llvm/ADT/ilist_iterator.h:139:0
#9 0x00007f26ce812d6f (anonymous namespace)::BBRemove::runOnModule(llvm::Module&) /home/rasha/llvm/llvm/lib/Transforms/BBRemove/BBRemove.cpp:79:0
#10 0x0000000002c4a2dc (opt+0x2c4a2dc)
#11 0x0000000002c4aa2c (opt+0x2c4aa2c)
#12 0x0000000002c4ac6d (opt+0x2c4ac6d)
#13 0x0000000001512cd4 (opt+0x1512cd4)
#14 0x00007f26cea6cf45 __libc_start_main /build/eglibc-ripdx6/eglibc-2.19/csu/libc-start.c:321:0
#15 0x00000000014f7a19 (opt+0x14f7a19)
Stack dump:
This error is issued after the first call of eraseFromParent.
BasicBlock::reverse_iterator I = (*b).rbegin();
BasicBlock::reverse_iterator Ie = (*b).rend();
stack<Instruction *> workList;
int i=0;
for ( ; I != Ie;I++)
{
if(i>0&&i<4){
workList.push_back(I);
i++;
}
else{
i++;
}
}
while(!workList.empty()){
Instruction *I=workList.pop();
I->eraseFromParent();
}
Do not modify instruction within the iterator; collect it first then modify.

c++ stl sort segmentation fault on vector

I recently encountering a pretty weird c++ STL sort behavior when I tried to apply a greater than compare function sort on a vector of strings, the detailed implementation could be found below:
//Compare the modify time of two files
bool cmp_modifytime(const base::String &file1, const base::String &file2)
{
struct stat statbuf1, statbuf2;
stat(file1.getBuffer(), &statbuf1);
stat(file2.getBuffer(), &statbuf2);
return statbuf1.st_mtime > statbuf2.st_mtime;
}
main routine:
std::vector<base::String> lFiles;
getFilesFromDir(dir, lFiles);
int fileCount = lFiles.size();
for(int i = 0; i <fileCount; i++)
{
tmp_str = dir;
tmp_str.append("/");
tmp_str.append(lFiles[i]);
lFiles[i] = tmp_str;
}
sort(lFiles.begin(), lFiles.end(), cmp_modifytime);
When I decode the crash, the backtrace looks like the following:
#0 0xf49a8940 in typeinfo for base::AString () from xxx
#1 0xf4919262 in cmp_modifytime (file1=..., file2=...) at xxx
#2 0xf491f91a in std::__unguarded_partition<__gnu_cxx::__normal_iterator<base::String*, std::vector<base::String> >, base::String, bool (*)(base::String const&, base::String const&)> (__first=..., __last=..., __pivot=..., __comp=0xf491923b <cmp_modifytime(base::String const&, base::String const&)>)
at xxx
#3 0xf491e5da in std::__unguarded_partition_pivot<__gnu_cxx::__normal_iterator<base::String*, std::vector<base::String> >, bool (*)(base::String const&, base::String const&)>
(__first=..., __last=..., __comp=0xf491923b <cmp_modifytime(base::String const&, base::String const&)>)
at xxx
#4 0xf491d0cc in std::__introsort_loop<__gnu_cxx::__normal_iterator<base::String*, std::vector<base::String> >, int, bool (*)(base::String const&, base::String const&)> (
__first=..., __last=..., __depth_limit=7, __comp=0xf491923b <cmp_modifytime(base::String const&, base::String const&)>)
at xxx
#5 0xf491d0ef in std::__introsort_loop<__gnu_cxx::__normal_iterator<base::String*, std::vector<base::String> >, int, bool (*)(base::String const&, base::String const&)> (
__first=..., __last=..., __depth_limit=8, __comp=0xf491923b <cmp_modifytime(base::String const&, base::String const&)>)
at xxx
#6 0xf491d0ef in std::__introsort_loop<__gnu_cxx::__normal_iterator<base::String*, std::vector<base::String> >, int, bool (*)(base::String const&, base::String const&)> (
__first=..., __last=..., __depth_limit=9, __comp=0xf491923b <cmp_modifytime(base::String const&, base::String const&)>)
at xxx
#7 0xf491c198 in std::sort<__gnu_cxx::__normal_iterator<base::String*, std::vector<base::String> >, bool (*)(base::String const&, base::String const&)> (__first=...,
__last=..., __comp=0xf491923b <cmp_modifytime(base::String const&, base::String const&)>)
at xxx
#8 0xf4919521 in main routine
The crash happened in the compare function, and interestingly I found that one of the input String object is an empty string:
(gdb) p file1
$1 = (const base::String &) #0x11db6180: {<base::Object> = {_vptr.Object = 0xf49a88e8}, <base::AString> = {_vptr.AString = 0xf49a8908}, buffer = 0x0, hashValue = 4294967295, size = -1, immutable = false}
(gdb) p file2
$2 = (const base::String &) #0x11db5f58: {<base::Object> = {_vptr.Object = 0xf49a8888}, <base::AString> = {_vptr.AString = 0xf49a88c8}, buffer = 0x11db6ba8 "testString123", hashValue = 4294967295, size = 13, immutable = false}
(gdb) p &file2
$3 = (const base::String *) 0x11db5f58
(gdb) p &file1
$4 = (const base::String *) 0x11db6180
And what's more interesting is that this empty string address is the same as the _M_finish of the vector I tried to do the sort, which means somehow sort takes the vector.end() into the compare function:
(gdb) p lFiles._M_impl._M_finish
$7 = (std::allocator<base::String>::pointer) 0x11db6180
This should never happen in my understanding.

Creating shared_ptr seems to cause segfault

I have the following function
static node_ptr make_node_ptr()
{
return node_ptr(new node());
}
where using node_ptr = std::shared_ptr<node>;
I tried to find my segmentation fault with valgrind and gdb. In both I get more or less the same stack trace.
Program received signal SIGSEGV, Segmentation fault.
0x00007fff8f5d7e82 in szone_malloc_should_clear () from /usr/lib/system/libsystem_malloc.dylib
(gdb) bt
#0 0x00007fff8f5d7e82 in szone_malloc_should_clear () from /usr/lib/system/libsystem_malloc.dylib
#1 0x00007fff8f5d7877 in malloc_zone_malloc () from /usr/lib/system/libsystem_malloc.dylib
#2 0x00007fff8f5d6395 in malloc () from /usr/lib/system/libsystem_malloc.dylib
#3 0x00000001000f17d8 in operator new(unsigned long) () from /usr/local/lib/gcc/4.9/libstdc++.6.dylib
#4 0x0000000100009c04 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<msc::scene_manager<float, int, 3ul>::node*> (this=0x7fff5f4002e8, __p=0x10059ffc0)
at /usr/local/Cellar/gcc49/4.9.2_1/include/c++/4.9.2/bits/shared_ptr_base.h:569
#5 0x0000000100008c78 in std::__shared_ptr<msc::scene_manager<float, int, 3ul>::node, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<msc::scene_manager<float, int, 3ul>::node> (this=0x7fff5f4002e0, __p=0x10059ffc0)
at /usr/local/Cellar/gcc49/4.9.2_1/include/c++/4.9.2/bits/shared_ptr_base.h:871
#6 0x00000001000079e5 in std::shared_ptr<msc::scene_manager<float, int, 3ul>::node>::shared_ptr<msc::scene_manager<float, int, 3ul>::node> (this=0x7fff5f4002e0, __p=0x10059ffc0)
at /usr/local/Cellar/gcc49/4.9.2_1/include/c++/4.9.2/bits/shared_ptr.h:113
#7 0x0000000100005bdc in msc::scene_manager<float, int, 3ul>::make_node_ptr () at ../../common/msc/scene.d/scene_manager_def.h:98
#8 0x00000001000037dd in msc::scene_manager<float, int, 3ul>::node::generate_wrapping_node (wrappee=...) at ../../common/msc/scene.d/node_impl.h:73
#9 0x0000000100003d53 in msc::scene_manager<float, int, 3ul>::node::generate_wrapping_node (nodes=...) at ../../common/msc/scene.d/node_impl.h:112
#10 0x0000000100004011 in msc::scene_manager<float, int, 3ul>::insert (this=0x7fff5f82ee90, root=..., other=...) at ../../common/msc/scene.d/scene_manager_impl.h:97
#11 0x0000000100006071 in msc::scene_manager<float, int, 3ul>::insert_if_leq (this=0x7fff5f82ee90, root=..., other=...) at ../../common/msc/scene.d/scene_manager_impl.h:127
The last 2 lines repeat endlessly, I guess at least, as I tried to continue until frame #6000 or smth.
Am I missing something or is the creation of this shared_ptr not allowed?
Edit
node_ptr scene_manager::insert(node_ptr & root, node_ptr other)
{
bool swapped = false;
if (root == nullptr)
root = other;
else
{
auto inside = msc::inside::test(*root, *other);
if (inside == msc::inside::NONE)
{
auto oldRoot = root;
root = node::generate_wrapping_node(
std::vector<node_c_ptr>{ oldRoot, other });
insert_if_leq(root, oldRoot);
}
else if ((swapped = (inside == msc::inside::FIRST)))
{
std::swap(root, other);
}
other = insert_if_leq(root, other);
}
return !swapped ? other : root;
}
node_ptr scene_manager::insert_if_leq(node_ptr root, node_ptr other)
{
node_ptr res = root;
if (are_similar(*root, *other))
msc::move_append(root->children, other->children);
else
{
auto idx = root->get_quadrant_idx(other->center);
res = insert(root->quadrants[idx], other);
}
return res;
}
These are the functions which repeat. msc is my own namespace.
As the functions are recursive insert calls insert_if_leq and vice versa, I had to make node_ptr root in insert_if_leq a reference, because the assignment in insert depended on it. The new function definitions are as follows:
node_ptr scene_manager::insert(node_ptr & root, node_ptr other)
node_ptr scene_manager::insert_if_leq(node_ptr & root, node_ptr other)

c++ : filling map of maps via map instance allocation from a vector of maps

part 2 to my : https://stackoverflow.com/questions/21780627/c-map-of-maps-typedef-doubts-queries
I then move ahead to create vectors (resizeable) of InnerMap, MiddlMap and do the following:
InnerMap inmap;
vector<InnerMap> vec_inmap;
vec_inmap.resize (8);
int vec_inmap_sz = 8;
vec_inmap.insert (vec_inmap.end (), 8, inmap);
vector<InnerMap>::iterator vec_inmap_it = vec_inmap.begin ();
InnerMap::iterator inmap_it;
MiddlMap mdmap, curr_mdmap;
vector<MiddlMap> vec_mdmap;
vec_mdmap.resize (8);
int vec_mdmap_sz = 8;
vec_mdmap.insert (vec_mdmap.end (), 8, mdmap);
vector<MiddlMap>::iterator vec_mdmap_it = vec_mdmap.begin ();
MiddlMap::iterator mdmap_it;
OuterMap otmap;
OuterMap::iterator otmap_it;
i.e. I store (empty) copies of inmap and mdmap (Q. is it that these copies are by reference ?) in the respective vectors, and then pick up these later from the vectors through the respective vector iterators, and then fill the maps accordingly. Here is how:
for (i = 0; i != trainSize; i++) {
...
if (curr_key_otmap != int_key) {
otmap[int_key] = *vec_mdmap_it;
vec_mdmap_it++;
mdmap_count++;
if (mdmap_count == vec_mdmap_sz) {
vec_mdmap_sz += 8;
vec_mdmap.resize (vec_mdmap_sz);
vec_mdmap.insert (vec_mdmap.end(), 8, mdmap);
}
curr_key_otmap = int_key;
curr_mdmap = otmap[curr_key_otmap];
}
mdmap_it = curr_mdmap.find (int_val);
if (mdmap_it == curr_mdmap.end ()) {
curr_mdmap[int_val] = *vec_inmap_it; <--
curr_mdmap[int_val][char_str] = 1;
vec_inmap_it++;
inmap_count++;
if (inmap_count == vec_inmap_sz) {
vec_inmap_sz += 8;
vec_inmap.resize (vec_inmap_sz);
vec_inmap.insert (vec_inmap.end(), 8, inmap);
}
} else {
inmap_it = (*mdmap_it).second.find (char_str);
if (inmap_it == (*mdmap_it).second.end ()) {
(*mdmap_it).second[char_str] = 1;
} else {
(*mdmap_it).second[char_str] += 1;
}
}
...
} //for ends
over the course of run time .. i get the following error at the <--ed line: could someone elaborate?
Program received signal SIGSEGV, Segmentation fault.
0x0804f9d4 in __gnu_cxx::new_allocator<std::pair<char* const, int> >::construct (this=0xbffff06f, __p=0x8057428, __val=...)
at /usr/include/c++/4.6/ext/new_allocator.h:108
108 { ::new((void *)__p) _Tp(__val); }
#0 0x0804fa2a in __gnu_cxx::new_allocator<std::pair<char* const, int> >::construct (this=0xbffff1bf, __p=0x8057428, __val=...)
at /usr/include/c++/4.6/ext/new_allocator.h:108
#1 0x0804f3e4 in std::_Rb_tree<char*, std::pair<char* const, int>, std::_Select1st<std::pair<char* const, int> >, std::less<char*>, std::allocator<std::pair<char* const, int> > >::_M_create_node (this=0x8098d1c, __x=...) at /usr/include/c++/4.6/bits/stl_tree.h:381
#2 0x0804e25f in std::_Rb_tree<char*, std::pair<char* const, int>, std::_Select1st<std::pair<char* const, int> >, std::less<char*>, std::allocator<std::pair<char* const, int> > >::_M_clone_node (this=0x8098d1c, __x=0xfffffffd) at /usr/include/c++/4.6/bits/stl_tree.h:427
#3 0x0804c645 in std::_Rb_tree<char*, std::pair<char* const, int>, std::_Select1st<std::pair<char* const, int> >, std::less<char*>, std::allocator<std::pair<char* const, int> > >::_M_copy (this=0x8098d1c, __x=0xfffffffd, __p=0x8098d20) at /usr/include/c++/4.6/bits/stl_tree.h:1036
#4 0x0804bda5 in std::_Rb_tree<char*, std::pair<char* const, int>, std::_Select1st<std::pair<char* const, int> >, std::less<char*>, std::allocator<std::pair<char* const, int> > >::operator= (this=0x8098d1c, __x=...) at /usr/include/c++/4.6/bits/stl_tree.h:945
#5 0x0804a714 in std::map<char*, int, std::less<char*>, std::allocator<std::pair<char* const, int> > >::operator= (this=0x8098d1c, __x=...)
at /usr/include/c++/4.6/bits/stl_map.h:255
#6 0x080493ff in MyProg::classify (trainData=..., testsData=...) at my_prog.cpp:83 <-- this is the line I marked
#7 0x08049c72 in main () at my_prog.cpp:200
Please ask me for edits/clarifications if anything is undecipherable.
You know what, your code is too big that i can't get it all but i think you should have this
vector<InnerMap*>::iterator vec_inmap_it = vec_inmap.begin ();
//instead of
vector<InnerMap>::iterator vec_inmap_it = vec_inmap.begin ();
try it
When you resize a vector, all iterators to that vector become invalid unless that space was already allocated with vector::reserve before the iterators were created. This is because if there is no available memory after currently allocated block, the data will be copied elsewhere. If the relocation happens, on next iteration, vec_inmap_it will then be pointing to unallocated memory that may have been overwritten. Thus undefined behaviour.
// inside for loop
if (mdmap_it == curr_mdmap.end ()) {
curr_mdmap[int_val] = *vec_inmap_it; // here you dereference vec_inmap_it
curr_mdmap[int_val][char_str] = 1;
vec_inmap_it++;
inmap_count++;
if (inmap_count == vec_inmap_sz) {
vec_inmap_sz += 8;
vec_inmap.resize (vec_inmap_sz); // here you resize the vector, vec_inmap_it is now invalid
vec_inmap.insert (vec_inmap.end(), 8, inmap);
}
...