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 :
<< : (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) :
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).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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; }
Merci.
Partager