Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Bus error (core dumped) with push_back() 1

Status
Not open for further replies.

hipparcos

Programmer
Jun 22, 2007
5
NL
Hi,
can anybody help me ?

I have a code Index which gave error message "Bus error (core dumped)" in the line push_back() function was called
as shown as following:


Index::Index(string fname) : vector<CatPair>(0), _range(vector<CatPair::index_type>(0))
{
ifstream is(fname.c_str());
if(is.fail()){
cerr << "Cannot access " + fname << endl;
exit(1);
}
while(is.good()){
CatPair cp;
cp.read(is);
if(is.eof())
continue;

push_back(cp);
//here I got the error (Bus error, core dumped);
}
is.close();
if(size() == 0) cout << "No events" << endl;
}


CatPair is a class as shown as following,


// this is CatPair.cc file
#include "CatPair.h"
#include <iostream>
using namespace std;

bool CatPair::eek:perator<(const CatPair& rhs) const
{
return second < rhs.second;
}

void CatPair::print(ostream& os) const
{
os << first << " " << second;
}

void CatPair::write(ostream& os) const
{
os.write(reinterpret_cast<const char*>(&first), sizeof(first));
os.write(reinterpret_cast<const char*>(&second), sizeof(second));
}

void CatPair::read(istream& is)
{

cout << " first=" << sizeof(first) << endl;
cout << " second=" << sizeof(second) << endl;

is.read(reinterpret_cast<char*>(&first), sizeof(first));
is.read(reinterpret_cast<char*>(&second), sizeof(second));


}


and the header file (CatPair.h)is following,

// this is CatPair.h file
#ifndef CATPAIR_H
#define CATPAIR_H

#include <string>
#include <iostream>
#include <utility>

class CatPair : public std::pair<unsigned int, std::string>
{
public:
CatPair(unsigned int f = 0, std::string s = " ") : std::pair<unsigned int,std::string>(f,s) { }
CatPair(std::string s) : std::pair<unsigned int,std::string>(0,s) { }
bool operator<(const CatPair& rhs) const;
void print(std::eek:stream& os) const;
void write(std::eek:stream& os) const;
void read(std::istream& os);

typedef unsigned int index_type;
typedef double value_type;

};

inline std::eek:stream& operator<<(std::eek:stream& os, const CatPair& p)
{
p.print(os); return os;
}

#endif



The Index Code works if I define the CatPair as a pair(int, double), but code gave error if I define the CatPair as a pair(int, string).

It is very appreciate if anybody can hive me a hand.

Thank you very much !!

Victor



 
1. Use CODE tag for snippets (see Process TGML link on the form).

2. See in CatPair::read():
Code:
is.read(reinterpret_cast<char*>(&second), sizeof(second));
Address of std::string object is not an address of the string text buffer. So you pass incorrect address to binary read function. Moreover, sizeof(second) i.e. sizeof(std::string) is not a size of any text buffer: it's sizeof of string descriptor.
Now you (in fact) destroy string object then try push_back it (with std::string copy constructor). Of course, this op crashed with bad descriptor (bad text buffer address and size).
There are many cases to fix situation, but it's common idea: you must invent a proper way to make std::string object as binary persistent (to upload/load string text to/from the file with write/read fstream ops).
 

Thank you so much for your reply.

You are right, the problem is in CatPair::read();
do you know a way to fix this situation ? or provide some more information ? I am realy stuck in this problem.

very appreciated !

 
Why are you reading and writing the string as binary?

If you ahve to do it, then one solution is to write out the size of the string first, then write out the string data. When you read in, read in the size first and then create a buffer of that size (use vector<char> buffer(size)) to read in the data. Once the data is read into the buffer, assign it to the string.

You cannot read directly into the internal data of the string, which is why you need the buffer.

An alternate solution is to determine the max size of your string and always write out and read in that size.
 
It's possible sceleton (add more robustness):
Code:
std::ostream& wbs(std::ostream& os, const std::string& s)
{
  int	n = s.size();
  os.write(reinterpret_cast<const char*>(&n),sizeof n);
  if (n)
     os.write(s.c_str(),n);
  return os;
}

std::istream& rbs(std::istream& is, std::string& s)
{
  int	n;
  if (is.read(reinterpret_cast<char*>(&n),sizeof n))
  {
     if (n > 0)
     {
        char* p = new char[n];
        if (is.read(p,n))
           s.assign(p,n);
        delete [] p;
     }
     else
        s.erase();
  }
  return is;
}
 

dear ArkM,

Thank you very much. I am very new about "std".

where should I insert your codes into my programme ?

I just append your codes in my class "GatPair" without changing our codes. But this did not work.

how to modify my methods "write", and "read" in the class "GatPair" ?

Thanks and regards,

 
Call these functions in write and read methods as
Code:
wbs(os,second); // write/binary string
and
rbs(is,second); // read/binary string
respectively instead of incorrect lines with sizeof(second).

Try to debug this simple improvisation before using.

Good luck!
 
when I tried to compile with your codes, I got the following error message, do you know how to fix it ? Thanks !

--------------------
g++ -I. -c -o CatPair.o CatPair.cc
CatPair.cc: In member function `void CatPair::write(std::eek:stream&) const':
CatPair.cc:32: error: invalid conversion from `void*' to `int'
CatPair.cc:32: error: initializing argument 2 of `std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::write(const _CharT*, std::streamsize) [with _CharT = char, _Traits = std::char_traits<char>]'
CatPair.cc: In member function `void CatPair::read(std::istream&)':
CatPair.cc:42: error: invalid conversion from `void*' to `int'
CatPair.cc:42: error: initializing argument 2 of `std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::read(_CharT*, std::streamsize) [with _CharT = char, _Traits = std::char_traits<char>]'
make: *** [CatPair.o] Error 1
---------------------------------
 
Present current code of read and write member functions, please.
 
Thanks. here is the current code;

Code:
#include "CatPair.h"
#include <iostream>
using namespace std;


std::ostream& wbs(std::ostream& os, const std::string& s);

std::istream& rbs(std::istream& is, std::string& s);

bool CatPair::operator<(const CatPair& rhs) const
{
  return second < rhs.second;
}

void CatPair::print(ostream& os) const
{
  os << first << " " << second;
}

void CatPair::write(ostream& os) const
{
  os.write(reinterpret_cast<const char*>(&first), sizeof(first));
  os.write(reinterpret_cast<const char*>(&second), wbs(os, second));
}

void  CatPair::read(istream& is)
{

   cout << " first=" << sizeof(first) << endl;   
   cout << " second=" << sizeof(second) << endl;   
  
  is.read(reinterpret_cast<char*>(&first), sizeof(first));
  is.read(reinterpret_cast<char*>(&second), rbs(is, second)); 

}


std::ostream& wbs(std::ostream& os, const std::string& s)
{
  int    n = s.size();
  os.write(reinterpret_cast<const char*>(&n),sizeof n);
  if (n)
     os.write(s.c_str(),n);
  return os;
}

std::istream& rbs(std::istream& is, std::string& s)
{
  int    n;
  if (is.read(reinterpret_cast<char*>(&n),sizeof n))
  {
     if (n > 0)
     {
        char* p = new char[n];
        if (is.read(p,n))
           s.assign(p,n);
        delete [] p;
     }
     else
        s.erase();
  }
  return is;
}
 
Please, try to understand the code before using. I set aside these functions (rbs/wbs) to read/write std::string objects, not to return a size for stream read/write functions.
May be my English is so bad, but (IMHO;) instead of lines is not the same thing that instead of sizeof(second) argument.
Try this:
Code:
void CatPair::write(ostream& os) const
{
  os.write(reinterpret_cast<const char*>(&first), sizeof(first));
//  os.write(reinterpret_cast<const char*>(&second), wbs(os, second));
  wbs(os,second);
}

void  CatPair::read(istream& is)
{

   cout << " first=" << sizeof(first) << endl;   
   cout << " second=" << sizeof(second) << endl;   
  
  is.read(reinterpret_cast<char*>(&first), sizeof(first));
//  is.read(reinterpret_cast<char*>(&second), rbs(is, second)); 
  rbs(is,second);
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top