Segmentation fault when working with binary file

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
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
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 :)
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';
}
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.
Your words parameter in populateFile should be const since it is not modified.
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';
}



Adam
Chris
Mark
Steve

Last edited on
Topic archived. No new replies allowed.