Segmentation fault when working with binary file
Sep 8, 2021 at 1:31pm UTC
HI guys,
doing something that I've done countless of times but nothing looks amiss to me yet I'm still getting a seg fault.
*sorry about the debugging prints
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
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
void populateFile(vector<string>& words){
ofstream out;
out.open("example.txt" ,ios::binary);
for (int i = 0; i < words.size(); ++i){
int size = words.at(i).size();
cout << "SIZE = " << size << endl;
out.write((char *)&size,sizeof (int ));
const char * c = words.at(i).c_str();
cout << c << endl;
out.write(c,size+1);
}
}
vector<string> read(){
ifstream in;
in.open("example.txt" ,ios::binary);
//in.seekg(0,ios::beg);
int size;
string word;
char * wc;
vector<string> names;
while (!in.eof()){
in.read((char *)&size,sizeof (int ));
cout << "num " << size << endl;
if (in.eof())
break ;
wc = new char [size+1];
in.read(wc,size+1);
if (in.eof())
break ;
cout << size << endl;
cout << wc << endl;
}
}
int main()
{
vector<string> names;
names.push_back("Adam" );
names.push_back("Chris" );
names.push_back("Mark" );
names.push_back("Steve" );
populateFile(names);
read();
Last edited on Sep 8, 2021 at 1:35pm UTC
Sep 8, 2021 at 2:07pm UTC
Your read function has no return:
main.cpp: In function 'std::vector<std::__cxx11::basic_string<char> > read()':
main.cpp:53:1: warning: no return statement in function returning non-void [-Wreturn-type]
Instead of looping on eof, you can loop on the successful extraction of data (the return of the in.read call).
You also have a memory leak originating from line 43.
Last edited on Sep 8, 2021 at 2:14pm UTC
Sep 8, 2021 at 3:20pm UTC
Wow I feel like an idiot, I didn't even think of the simplest fix. I should have checked my compiler warnings.
and yes @43 I should call delete but didn't include that in the code,
Thanks Ganado :)
Sep 8, 2021 at 3:31pm UTC
Your code could be simpler:
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
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
void populateFile(vector<string>& words)
{
ofstream out("example.txt" , ios::binary);
if (!out)
{
cout << "Error opening input file\n" ;
return ;
}
for (auto & str : words)
{
auto size = str.size();
//cout << "SIZE = " << size << endl;
out.write((char *)&size, sizeof (size));
//cout << str << endl;
out.write(str.c_str(), size);
}
}
vector<string> read()
{
vector<string> names;
ifstream in("example.txt" , ios::binary);
if (!in)
{
cout << "Error opening input file\n" ;
return names;
}
size_t size;
string word;
while (!in.eof())
{
in.read((char *)&size, sizeof (size));
//cout << "num " << size << endl;
if (in.eof())
break ;
word.resize(size);
in.read((char *)&word[0], size);
names.push_back(word);
if (in.eof())
break ;
//cout << size << endl;
//cout << word << endl;
}
return names;
}
int main()
{
vector<string> names{"Adam" , "Chris" , "Mark" , "Steve" };
populateFile(names);
vector<string> names2 = read();
for (const auto & s : names2)
cout << s << '\n' ;
}
Sep 8, 2021 at 3:34pm UTC
could be although I generally opt for c++98 syntax which is not a good habit to have, I guess the books and resources that I learned from generally thought c++98.
Sep 8, 2021 at 4:04pm UTC
Your words parameter in populateFile should be const since it is not modified.
Sep 8, 2021 at 4:53pm UTC
As C++17:
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
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <memory>
constexpr const char * fnam {"example.txt" };
using Array = std::vector<std::string>;
using T = Array::value_type::size_type;
void populateFile(const Array& words) {
std::ofstream out(fnam, std::ios::binary);
for (const auto & w : words) {
const T size {w.size() + 1};
out.write((char *)&size, sizeof (size));
out.write(w.c_str(), size);
}
}
auto read() {
std::ifstream in(fnam, std::ios::binary);
Array names;
for (T size; in.read((char *)&size, sizeof (size)); )
if (const auto wc {std::make_unique<char []>(size)}; in.read(wc.get(), size))
names.emplace_back(wc.get());
return names;
}
int main()
{
const Array names {"Adam" , "Chris" , "Mark" , "Steve" };
populateFile(names);
const auto filnames {read()};
for (const auto & n : filnames)
std::cout << n << '\n' ;
}
Last edited on Sep 8, 2021 at 4:57pm UTC
Topic archived. No new replies allowed.