-
Notifications
You must be signed in to change notification settings - Fork 193
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
C++11: segfault in debug mode for arrays #1105
Comments
I think, the best solution is to move read just after creating object, but then this can create a memory leak in C++98 target if // This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
#include "debug_array_user.h"
debug_array_user_t::debug_array_user_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, debug_array_user_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root ? p__root : this;
m_one_cat = 0;
m_array_of_cats = 0;
}
void debug_array_user_t::_read() {
m_one_cat = new cat_t(m__io, this, m__root);
m_one_cat->_read();
m_array_of_cats = new std::vector<cat_t*>();
const int l_array_of_cats = 3;
for (int i = 0; i < l_array_of_cats; i++) {
cat_t* _t_array_of_cats = new cat_t(m__io, this, m__root);
m_array_of_cats->push_back(_t_array_of_cats);
_t_array_of_cats->_read();
}
}
debug_array_user_t::~debug_array_user_t() {
_clean_up();
}
void debug_array_user_t::_clean_up() {
if (m_one_cat) {
delete m_one_cat; m_one_cat = 0;
}
if (m_array_of_cats) {
for (std::vector<cat_t*>::iterator it = m_array_of_cats->begin(); it != m_array_of_cats->end(); ++it) {
delete *it;
}
delete m_array_of_cats; m_array_of_cats = 0;
}
}
debug_array_user_t::cat_t::cat_t(kaitai::kstream* p__io, debug_array_user_t* p__parent, debug_array_user_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
}
void debug_array_user_t::cat_t::_read() {
m_meow = m__io->read_u1();
}
debug_array_user_t::cat_t::~cat_t() {
_clean_up();
}
void debug_array_user_t::cat_t::_clean_up() {
} Because in C++98 target we do not want to use any smart pointers because they can absence, we can, however, create a custom, very limited smart pointer type, which will only exist to delete memory allocated for object if its void debug_array_user_t::_read() {
m_one_cat = new cat_t(m__io, this, m__root);
m_one_cat->_read();
m_array_of_cats = new std::vector<cat_t*>();
const int l_array_of_cats = 3;
for (int i = 0; i < l_array_of_cats; i++) {
safe_read_helper<cat_t> _t_array_of_cats_helper = safe_read_helper<cat_t>(new cat_t(m__io, this, m__root));
cat_t* _t_array_of_cats = _t_array_of_cats_helper.read();
m_array_of_cats->push_back(_t_array_of_cats);
}
} The helper is very simple and limited: /// Will work only with concrete types
/// Live only on stack. Destroyed just after calling `read()`
template<class T>
class safe_read_helper {
T* m_ptr;
public:
safe_read_helper(T* ptr) : m_ptr(ptr) {}
~safe_read_helper() { delete this->m_ptr; }
T* read() {
T* ptr = this->m_ptr;
ptr->_read();
this->m_ptr = 0;
return ptr;
}
} |
Currently C++ generator when uses smart pointers generates incorrect code that uses
unique_ptr
after it was moved into the vector:That is the reason why
DebugArrayUser
test on https://ci.kaitai.io/ is segfaulted on C++11 with messagememory access violation at address: 0x8: no mapping at fault address
.This is the common problem: in debug mode reading is performed after placing new object into container, but in no debug mode it is readed in constructor, i. e. before placing into container. That is very unpleasant situation, because debug mode ideally should not change behavior.
The text was updated successfully, but these errors were encountered: