Erreur de segmentation sur boost :: multi_array

Le code suivant donne une erreur de segmentation:

#include  #include  #include "binItr.h" #include  using namespace std; int main(){ const char * xifile = "results/feretxiG1155V0P5T231K10.bin"; const uint pSize = 5; const uint T = 231; ifstream xiFileId(xifile, ios::binary); typedef boost::multi_array array_type; array_type xi(boost::extents[T][pSize + 1]); //the ii_t class in the following line is taken from http://stackoverflow.com/questions/1855704/c-binary-file-io-to-from-containers-other-than-char-using-stl-algorithms written by http://stackoverflow.com/users/14065/loki-astari ii_t xi_in(xiFileId); copy(xi_in, ii_t(), xi.data()); return 0; } 

Le fichier binary en entrée contient unsigned int données unsigned int et sa taille, indiquée par ls -l est 231 * (5 + 1) 4 = 5544 octets. J’ai essayé de lire le fichier et de stocker les données dans un vecteur et de constater que la taille du vecteur est 231 (5 + 1) = 1386. L’parsing du fichier de base à l’aide de gdb donne le résultat suivant.

  Program terminated with signal 6, Aborted. #0 0x00007fb71130ea75 in raise (sig=) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 64 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory. in ../nptl/sysdeps/unix/sysv/linux/raise.c (gdb) bt #0 0x00007fb71130ea75 in raise (sig=) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 #1 0x00007fb7113125c0 in abort () at abort.c:92 #2 0x00007fb7113484fb in __libc_message (do_abort=, fmt=) at ../sysdeps/unix/sysv/linux/libc_fatal.c:189 #3 0x00007fb7113525b6 in malloc_printerr (action=3, str=0x7fb711425cd8 "double free or corruption (!prev)", ptr=) at malloc.c:6266 #4 0x00007fb711358e83 in __libc_free (mem=) at malloc.c:3738 #5 0x00000000004018c4 in __gnu_cxx::new_allocator::deallocate (this=0x7fffc618d2f8, __p=0x2295290) at /usr/include/c++/4.4/ext/new_allocator.h:95 #6 0x000000000040152f in boost::multi_array<unsigned int, 2ul, std::allocator >::deallocate_space (this=0x7fffc618d290) at /usr/include/boost/multi_array.hpp:484 #7 0x0000000000401077 in boost::multi_array<unsigned int, 2ul, std::allocator >::~multi_array (this=0x7fffc618d290, __in_chrg=) at /usr/include/boost/multi_array.hpp:468 #8 0x0000000000400d4e in main () at segTest.cpp:30 

Aucune suggestion? Merci.

Le problème est que la classe iterator d’entrée ii_t<> de la réponse du responsable de système référencé “lit” un trop grand nombre d’éléments, car le istream ne istream pas EOF tant que le déréférencement de l’iterator après celui qui a renvoyé le dernier élément de la liste. fichier. L’élément de données renvoyé en multi_array le bloc de mémoire alloué dans l’object multi_array .

Si vous modifiez la classe ii_t<> comme suit, vous devriez obtenir un meilleur comportement:

 template struct ii_t: public iterator { ii_t(std::istream& str) :m_str(&str) {} ii_t() :m_str(NULL) {} ii_t& operator++() {return *this;} // increment does nothing. ii_t& operator++(int){return *this;} T& operator*() { // On the de-reference we actuall read the data into a local //// static //// // Thus we can return a reference static T result; m_str->read(reinterpret_cast(&result),sizeof(T)); return result; } // If either iterator has a NULL pointer then it is the end() of stream iterator. // Input iterators are only equal if they have read past the end of stream. bool operator!=(ii_t const& rhs) { // we need to make sure we're not just about to hit EOF // if we already haven't if (m_str && m_str->good()) { char dummy; m_str->read(&dummy,1); if (m_str->good()) { m_str->putback(dummy); } } if (rhs.m_str && rhs.m_str->good()) { char dummy; rhs.m_str->read(&dummy,1); if (rhs.m_str->good()) { rhs.m_str->putback(dummy); } } bool lhsPastEnd = (m_str == NULL) || (!m_str->good()); bool rhsPastEnd = (rhs.m_str == NULL) || (!rhs.m_str->good()); return !(lhsPastEnd && rhsPastEnd); } private: std::istream* m_str; }; 

Les modifications pertinentes sont dans la fonction d’ bool operator!=(ii_t const& rhs) , où, si nécessaire, une lecture factice est exécutée (puis annulée) sur le istream pour déterminer si celui-ci est à l’état EOF.

Notez que je ne prétends pas que c’est la meilleure technique pour gérer la situation EOF , mais cela semble fonctionner.