How can i fix Onnxruntime session->Run problem? - c++

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.

Related

QT: sqlite and qlist issue

I have a multithread application which accesses a DB from multiple thread, and randomically I fall in this error (not the same query)...
__GI___libc_free (mem=0x7fff00042660) at /build/glibc-vjB4T1/glibc-2.28/malloc/malloc.c:3093
QList<_RData>::node_destruct (this=0x7fffebffce08, from=0x7fffe4037fc0, to=0x7fffe4037fd8) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qlist.h:494
QList<_RData>::dealloc (this=0x7fffebffce08, data=0x7fffe4037fb0) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qlist.h:865
QList<_RData>::~QList (this=0x7fffebffce08) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qlist.h:827
QList<_RData>::operator= (this=0x55555565cd68, other=#0x7fffebffd880: {<QListSpecialMethods<_RoomData>> = {<No data fields>}, {p = {static shared_null = {ref = {atomic = {_q_value = {<std::__atomic_base<int>> = {static _S_alignment = 4, _M_i = -1}, <No data fields>}}}, alloc = 0, begin = 0, end = 0, array = {0x0}}, d = 0x7ffff6ff76c0 <QListData::shared_null>}, d = 0x7ffff6ff76c0 <QListData::shared_null>}}) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qlist.h:159
AMProcess::doActionAM (this=0x55555565cc30) at /smart/software/AudioIO/AMProcess.cpp:453
QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (AMProcess::*)()>::call(void (AMProcess::*)(), AMProcess*, void**) (f=(void (AMProcess::*)(AMProcess * const)) 0x5555555b943c <AMProcess::doActionAM()>, o=0x55555565cc30, arg=0x7fffebffee40) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:134
QtPrivate::FunctionPointer<void (AMProcess::*)()>::call<QtPrivate::List<>, void>(void (AMProcess::*)(), AMProcess*, void**) (f=(void (AMProcess::*)(AMProcess * const)) 0x5555555b943c <AMProcess::doActionAM()>, o=0x55555565cc30, arg=0x7fffebffee40) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:167
QtPrivate::QSlotObject<void (AMProcess::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (which=1, this_=0x555555661cf0, r=0x55555565cc30, a=0x7fffebffee40, ret=0x0) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:396
QMetaObject::activate(QObject*, int, int, void**) () at null:
QThread::started(QThread::QPrivateSignal) () at null:
?? () at null:
start_thread (arg=<optimized out>) at /build/glibc-vjB4T1/glibc-2.28/nptl/pthread_create.c:486
clone () at /build/glibc-vjB4T1/glibc-2.28/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:95
This is some snippets of my code
rData = DBRManager::ReadRData("R", m_connName);
if (rData.size() > 0) {
}
...and this is the query
QList<_RData> DBRManager::ReadRData(QString tbName, QString dbName)
{
QList<_RData> records;
QSqlQuery query(QSqlDatabase::database(dbName));
query.setForwardOnly(true);
query.exec("DSQLITE_THREADSAFE=2");
query.exec("SELECT * FROM " + tbName);
while (query.next()) {
_RData data;
data.id = query.value("id").toInt();
data.type = query.value("type").toInt();
records.append(data);
}
query.finish();
return records;
}

AddSymbolicGradients is failing on recursive implementation

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 ()

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.

std::remove_copy_if_ valgrind bytes in block are possibly lost in loss record

Exploring a valgrind report in search of a huge memleak, it seems that the following line produces the biggest threat over lots of calls:
std::remove_copy_if(raw_word.begin(), raw_word.end(),
std::back_inserter(word), std::ptr_fun<int, int>(&std::ispunct));
CODE
char * payload = /* acquire somehow */
int whitespace;
char * p_word = NULL;
for(whitespace = 0; whitespace < payload_len; whitespace ++)
{
if(isspace(payload[whitespace]))
{
payload[whitespace] = 0;
if(p_word != NULL)
{
std::string raw_word(p_word), word;
// remove punctuation
std::remove_copy_if(raw_word.begin(), raw_word.end(),
std::back_inserter(word), std::ptr_fun<int, int>(&std::ispunct));
if (/* some condition */)
{
// copy and consume `word`
}
}
p_word = NULL;
}
else
{
if(p_word == NULL)
p_word = payload + whitespace;
}
}
Since I'm not very acquainted with memleak hunting, the absence of an explicit new makes me confused about the placement of a corresponding delete.
LOG
848,631 bytes in 24,592 blocks are possibly lost in loss record 1,334 of 1,339
at : operator new(unsigned long) (vg_replace_malloc.c:324)
by : std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
by : std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
by : std::string::reserve(unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
by : push_back (basic_string.h:1053)
by : operator= (stl_iterator.h:440)
by : std::back_insert_iterator<std::string> std::remove_copy_if<__gnu_cxx::__normal_iterator<char*, std::string>, std::back_insert_iterator<std::string>, std::pointer_to_unary_function<int, int> >(__gnu_cxx::__normal_iterator<char*, std::string>, __gnu_cxx::__normal_iterator<char*, std::string>, std::back_insert_iterator<std::string>, std::pointer_to_unary_function<int, int>) (stl_algo.h:951)
// WordsSourceKafka::_do_async() contains the snipped code
by : blockmon::WordsSourceKafka::_do_async() (WordsSourceKafka.cpp:332)
by : blockmon::Block::run() (Block.cpp:349)
by : operator() (ThreadHandler.hpp:149)
by : __invoke<blockmon::ThreadHandler> (functional:235)
by : operator()<> (functional:468)
by : _M_invoke<> (functional:1598)
by : operator() (functional:1586)
by : std::thread::_Impl<std::_Bind_simple<std::reference_wrapper<blockmon::ThreadHandler> ()> >::_M_run() (thread:115)
by : ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
by : start_thread (pthread_create.c:304)
by : clone (clone.S:112
I can't tell you why, but this solved the valgrind record.
auto isPunct = [](char c)
{
return std::ispunct(static_cast<unsigned char>(c));
};
raw_word.erase(std::remove_if(raw_word.begin(), raw_word.end(), isPunct),
raw_word.end());

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);
}
...