Erreur de segmentation sur ifstream.close()
Bonjour,
Je rencontre un problème pour la création d'une méthode de lecture dans un fichier.
j'utilise un pointeur de ifstream déclaré et initialisé dans la méthode, puis je fais un open sur mon fichier en mode texte. Cette partie fonctionne très bien.
Ensuite, je ferme mon fichier pour pouvoir le ré-ouvrir en mode binaire. Je me replace là ou je m'étais arrêté en mode texte et je lis des entiers. La lecture se passe très bien aussi.
Mais l'erreur se trouve lorsque je re-ferme le ifstream (que ce soit avec close(), le destructeur ou rien du tout (destruction automatique des variables à la fin de la méthode)). Lors de l'exécution, j'ai une erreur de segmentation !! :'(
voici le résultat de backtrace dans gdb :
Citation:
<< : (0.742781,3.24967,-0)
=== Test 1 ===
test
Program received signal SIGSEGV, Segmentation fault.
0xb7d25e68 in _int_free () from /lib/tls/i686/cmov/libc.so.6
(gdb) bt
#0 0xb7d25e68 in _int_free () from /lib/tls/i686/cmov/libc.so.6
#1 0xb7d26456 in free () from /lib/tls/i686/cmov/libc.so.6
#2 0xb7f020b1 in operator delete () from /usr/lib/libstdc++.so.6
#3 0xb7f0210d in operator delete[] () from /usr/lib/libstdc++.so.6
#4 0xb7ea888f in std::basic_filebuf<char, std::char_traits<char> >::_M_destroy_internal_buffer () from /usr/lib/libstdc++.so.6
#5 0xb7ea9e01 in std::basic_filebuf<char, std::char_traits<char> >::close ()
from /usr/lib/libstdc++.so.6
#6 0xb7eab355 in std::basic_ifstream<char, std::char_traits<char> >::close ()
from /usr/lib/libstdc++.so.6
#7 0x0804b579 in Image::fromFile (this=0xbfd6e1a0, filename=
{static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0xbfd6de6c "\024�k\b"}}) at Image.cpp:192
#8 0x0804bc2c in Image (this=0xbfd6e1a0, filename=
{static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0xbfd6e1d0 "\024�k\b��\004\b��ֿ"}}) at Image.cpp:15
#9 0x0804a6a4 in main () at main.cpp:124
(gdb)
et le code de ma méthode (avec le header de la classe) :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
#ifndef IMAGE_H
#define IMAGE_H
#include <string>
using namespace std;
class Image {
public:
struct pixel {
unsigned short r;
unsigned short g;
unsigned short b;
};
// Exceptions
class OutOfRangeException {};
private:
pixel *m_pix;
int m_width, m_height;
string m_filename;
//fstream * m_file;
public:
Image (int width, int height);
Image (string filename);
Image (const Image & src);
~Image ();
int getWidth () const;
int getHeight () const;
pixel getPixel (int x, int y) const;
void setPixel (int x, int y, pixel p);
void setPixelRow (int y, pixel row[]);
void setPixelColumn (int x, pixel col[]);
void toFile (string filename) const;
void fromFile (string filename);
const Image & operator= (const Image & src);
bool operator== (const Image & p) const;
bool operator!= (const Image & p) const;
};
#endif
//==================================================================
void Image::fromFile (string filename) {
// Ouverture du fichier
ifstream * m_file = new ifstream();
m_file->open(filename.c_str(), ios_base::in);
if (!m_file) {
//cerr << "Ouverture impossible de " << filename << endl;
return;
}
// Variables de lecture
char byte;
unsigned short dbyte;
unsigned short maxcolor;
// Magic number
*m_file >> byte;
if (byte != 'P')
return;
*m_file >> byte;
if (byte != '6')
return;
// Width
*m_file >> dbyte;
if (dbyte <= 0)
return;
m_width = dbyte;
// Height
*m_file >> dbyte;
if (dbyte <= 0)
return;
m_height = dbyte;
// Max color
*m_file >> dbyte;
if (dbyte <= 0)
return;
maxcolor = dbyte;
// Init pixel map
m_pix = new pixel[m_width*m_height];
// Ouverture en mode binaire
int position = m_file->tellg();
m_file->close();
delete m_file;
m_file = new ifstream();
m_file->open(filename.c_str(), ios_base::in|ios_base::binary);
if (!m_file) {
//cerr << "Ouverture binaire impossible de " << filename << endl;
return;
}
m_file->seekg(position+1, ios::beg); // skips single whitespace
// Pixels
for (int x=0; x<m_height; x++) {
for (int y=0; y<m_width; y++) {
if (maxcolor < 256) { // Couleur sur 1 octet
m_file->read(reinterpret_cast<char *>(&(m_pix[ x + m_width*y ].r)), 1);
m_file->read(reinterpret_cast<char *>(&(m_pix[ x + m_width*y ].g)), 1);
m_file->read(reinterpret_cast<char *>(&(m_pix[ x + m_width*y ].b)), 1);
}
else { // couleur sur 2 octets
m_file->read(reinterpret_cast<char *>(&(m_pix[ x + m_width*y ].r)), 2);
m_file->read(reinterpret_cast<char *>(&(m_pix[ x + m_width*y ].g)), 2);
m_file->read(reinterpret_cast<char *>(&(m_pix[ x + m_width*y ].b)), 2);
}
}
}
cerr << "test" << endl;
m_file->close();
delete m_file;
} |
Ah oui et je pense pas que ca change quoi que ce soit, mais cette méthode je l'appelle aussi depuis un constructeur (c'est ce que j'utilise pour faire le test).
Merci.