sig-fault with objects creation

G

Gary Wessle

Hi

the code below prints out part of the list then "Segmentation fault",
but if I comment out the line " Mytype tmp( ss.c_str() ); " it prints
out the whole list.
please take a look, what did I do wrong for it to sig-fault?

thank you


//****************************************************************

#include <boost/tokenizer.hpp>
#include <string>
#include <iostream>
using namespace std;
using namespace boost;

class Mytype {
protected:
char _fir[40];
char _sec[40];
char _all[80];
public:
const char* fir() const;
const char* sec() const;
const char* all() const;
Mytype(const char* all);
};

Mytype::Mytype(const char* all)
{
strncpy(_fir, all, 3);
_fir[3]='\0';
strncpy(_sec, all+4, 3);
_sec[3]='\0';
strcat(_all, _fir);
strcat(_all, _sec);
}
const char* Mytype::fir()const { return _fir;}
const char* Mytype::sec()const { return _sec;}
const char* Mytype::all()const { return _all;}


int main(){

string s = "ade-ddf,wee-see,dfe-wef,ade-ddf,wee-see,dfe-wef,ade-ddf,wee-see,dfe-wef,ade-ddf,wee-see,dfe-wef,ade-ddf,wee-see,dfe-wef,ade-ddf,wee-see,dfe-wef,ade-ddf,wee-see,dfe-wef,ade-ddf,wee-see,dfe-wef";
char_separator<char> sep(",");
typedef tokenizer<char_separator<char> > tokenizer;
tokenizer tok(s, sep);
short x = 0;
for (tokenizer::iterator i=tok.begin(); i!=tok.end(); ++i){

cout << ++x << " " << *i << endl;

string ss(*i);
Mytype tmp( ss.c_str() ); // <<<<<<<<<<<<<<<< comment this

}
}
 
P

peter koch

Gary Wessle skrev:
Hi
[snip]
class Mytype {
protected:
char _fir[40];
char _sec[40];
char _all[80];
public:
const char* fir() const;
const char* sec() const;
const char* all() const;
Mytype(const char* all);
};

Mytype::Mytype(const char* all)
{
strncpy(_fir, all, 3);
_fir[3]='\0';
strncpy(_sec, all+4, 3);
_sec[3]='\0';
strcat(_all, _fir);
[snip]
_all is not initialised here. That makes strcat pretty meaningless. Use
std::string instead - always avoid low-level stuff when you can.

/Peter
 
G

Gary Wessle

peter koch said:
Gary Wessle skrev:
Hi
[snip]
class Mytype {
protected:
char _fir[40];
char _sec[40];
char _all[80];
public:
const char* fir() const;
const char* sec() const;
const char* all() const;
Mytype(const char* all);
};

Mytype::Mytype(const char* all)
{
strncpy(_fir, all, 3);
_fir[3]='\0';
strncpy(_sec, all+4, 3);
_sec[3]='\0';
strcat(_all, _fir);
[snip]
_all is not initialised here. That makes strcat pretty meaningless. Use
std::string instead - always avoid low-level stuff when you can.

/Peter

I would want to avoid low-level stuff, but this is different. I am
trying to emulate Big-Bucks-Inc library to test it with my C++ project
before actually using it.
 
G

Gary Wessle

peter koch said:
Gary Wessle skrev:
Hi
[snip]
class Mytype {
protected:
char _fir[40];
char _sec[40];
char _all[80];
public:
const char* fir() const;
const char* sec() const;
const char* all() const;
Mytype(const char* all);
};

Mytype::Mytype(const char* all)
{
strncpy(_fir, all, 3);
_fir[3]='\0';
strncpy(_sec, all+4, 3);
_sec[3]='\0';
strcat(_all, _fir);
[snip]
_all is not initialised here. That makes strcat pretty meaningless. Use
std::string instead - always avoid low-level stuff when you can.

/Peter

so who would you initialize it?
 
D

David Harmon

On 20 Nov 2006 06:41:42 +1100 in comp.lang.c++, Gary Wessle
Mytype::Mytype(const char* all)
{
strncpy(_fir, all, 3);
_fir[3]='\0';
strncpy(_sec, all+4, 3);
_sec[3]='\0';
strcat(_all, _fir);
[snip]
_all is not initialised here. That makes strcat pretty meaningless. Use
std::string instead - always avoid low-level stuff when you can.

/Peter

so who would you initialize it?

Who? Where? Why did you switch to strcat() for that one instead of the
mostly OK strcpy() of the two similar vars that preceded it? The answer
to that should tell you What it should be initialized to.
 
B

BobR

Gary Wessle wrote in message ...
[snip]

so who would you initialize it?

class Mytype {
protected:

std::string All;

Mytype::Mytype( char const *all) : All( all, all+3){}

const char* Mytype::all(){ return All.c_str(); }
 
G

Gary Wessle

David Harmon said:
On 20 Nov 2006 06:41:42 +1100 in comp.lang.c++, Gary Wessle
Mytype::Mytype(const char* all)
{
strncpy(_fir, all, 3);
_fir[3]='\0';
strncpy(_sec, all+4, 3);
_sec[3]='\0';
strcat(_all, _fir);
[snip]
_all is not initialised here. That makes strcat pretty meaningless. Use
std::string instead - always avoid low-level stuff when you can.

/Peter

so who would you initialize it?

Who? Where? Why did you switch to strcat() for that one instead of the
mostly OK strcpy() of the two similar vars that preceded it? The answer
to that should tell you What it should be initialized to.


strncpy(_all, all, 3);
_pair[3]='\0';
strcat(_all, _sec);
 
D

druberego

C/C++ does not zero memory like JAVA or some other languages.
Therefore when the constructor starts the contents of _all is
basically undefined.

strcat() attempt to find the end of the string _all. The end is
recognized by the presence of a '\0' character. Which you
may not have. So strcat() merrily walks off the end of your
_all string while looking for where to append data.

The other posters are correct. use std::string instead. It
is much less prone to such errors.

But here's your answer...

Mytype::Mytype(const char* all)
{
strncpy(_fir, all, 3);
_fir[3]='\0';
strncpy(_sec, all+4, 3);
_sec[3]='\0';
strcpy(_all, _fir); // guarantees that the '\0' from _fir
// is copied. You are assuming that
// _all is to be treated as having
// contained an empty string "" and
// thus an append is the same as a
// copy which does not search for
// end of _all first.
strcat(_all, _sec); // now strcat() is guaranteed to
// encounter a '\0' while searching
// for the append location.
}

and you could have done:
_all[0] = '\0';
just prior to the first strcat() instead of what I
provided.

- Jeff

Gary said:
Hi

the code below prints out part of the list then "Segmentation fault",
but if I comment out the line " Mytype tmp( ss.c_str() ); " it prints
out the whole list.
please take a look, what did I do wrong for it to sig-fault?

thank you


//****************************************************************

#include <boost/tokenizer.hpp>
#include <string>
#include <iostream>
using namespace std;
using namespace boost;

class Mytype {
protected:
char _fir[40];
char _sec[40];
char _all[80];
public:
const char* fir() const;
const char* sec() const;
const char* all() const;
Mytype(const char* all);
};

Mytype::Mytype(const char* all)
{
strncpy(_fir, all, 3);
_fir[3]='\0';
strncpy(_sec, all+4, 3);
_sec[3]='\0';
strcat(_all, _fir);
strcat(_all, _sec);
}
const char* Mytype::fir()const { return _fir;}
const char* Mytype::sec()const { return _sec;}
const char* Mytype::all()const { return _all;}


int main(){

string s = "ade-ddf,wee-see,dfe-wef,ade-ddf,wee-see,dfe-wef,ade-ddf,wee-see,dfe-wef,ade-ddf,wee-see,dfe-wef,ade-ddf,wee-see,dfe-wef,ade-ddf,wee-see,dfe-wef,ade-ddf,wee-see,dfe-wef,ade-ddf,wee-see,dfe-wef";
char_separator<char> sep(",");
typedef tokenizer<char_separator<char> > tokenizer;
tokenizer tok(s, sep);
short x = 0;
for (tokenizer::iterator i=tok.begin(); i!=tok.end(); ++i){

cout << ++x << " " << *i << endl;

string ss(*i);
Mytype tmp( ss.c_str() ); // <<<<<<<<<<<<<<<< comment this

}
}
 
F

Frank Puck

Gary Wessle said:
Mytype::Mytype(const char* all)
{
strncpy(_fir, all, 3);
_fir[3]='\0';
strncpy(_sec, all+4, 3);
_sec[3]='\0';
strcat(_all, _fir);
strcat(_all, _sec);
}


please do yourself a favor and use std::string instead of raw char *.
You're virtually certain to program buffer overflows if you try to to this
yourself.
 
P

peter koch

Gary Wessle skrev:
peter koch said:
Gary Wessle skrev:
Hi
[snip]
class Mytype {
protected:
char _fir[40];
char _sec[40];
char _all[80];
public:
const char* fir() const;
const char* sec() const;
const char* all() const;
Mytype(const char* all);
};

Mytype::Mytype(const char* all)
{
strncpy(_fir, all, 3);
_fir[3]='\0';
strncpy(_sec, all+4, 3);
_sec[3]='\0';
strcat(_all, _fir);
[snip]
_all is not initialised here. That makes strcat pretty meaningless. Use
std::string instead - always avoid low-level stuff when you can.

/Peter

so who would you initialize it?
I would simply use str(n)cpy instead of strcat. strcat requieres both
arguments to be valid strings (where strcat(a,b) basically corresponds
to a = a + b (if a and b were strings)).

/Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,125
Latest member
VinayKumar Nevatia_
Top