Smart questions
Smart answers
Smart people
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Member Login

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips now!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

Join Tek-Tips
*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

LINK TO THIS FORUM!

Add Stickiness To Your Site By Linking To This Professionally Managed Technical Forum.
Just copy and paste the
code below into your site.

Partner With Us!

"Best Of Breed" Forums Add Stickiness To Your Site
Partner Button
(Download This Button Today!)

Feedback

"...A lot of the information I've found at this site would've taken me forever if I'd have attempted to research it on my own. Thanks again."

Geography

Where in the world do Tek-Tips members come from?

Bus error (core dumped) with push_back() Helpful Member! 

hipparcos (Programmer)
22 Jun 07 4:24
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::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), 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::ostream& os) const;
  void write(std::ostream& os) const;
  void read(std::istream& os);

  typedef unsigned int index_type;
  typedef double value_type;

};

inline std::ostream& operator<<(std::ostream& 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



Helpful Member!  ArkM (IS/IT--Management)
22 Jun 07 6:05
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).
hipparcos (Programmer)
22 Jun 07 6:34

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 !

uolj (Programmer)
22 Jun 07 14:59
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.
ArkM (IS/IT--Management)
25 Jun 07 1:50
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;
}
hipparcos (Programmer)
25 Jun 07 5:37

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,

 
ArkM (IS/IT--Management)
25 Jun 07 6:02
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!
hipparcos (Programmer)
25 Jun 07 10:56
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::ostream&) 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
---------------------------------
ArkM (IS/IT--Management)
26 Jun 07 0:48
Present current code of read and write member functions, please.
hipparcos (Programmer)
26 Jun 07 3:38
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;
}
ArkM (IS/IT--Management)
26 Jun 07 6:02
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);
}

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Back To Forum

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close