segfault strlen

D

danielesalatti

Hello!!
I'm studying c++ and I'm trying to get a little piece of code working,
but I'm getting a segfault with strlen here:

void tabhash::set (url *U) {
uint hash = U->hashCode();
char* url = U->giveUrl();
char* chash = (char*)hash;

char* Insert1="INSERT INTO sep_hashtable VALUES (";
char* Insert2=",0,'";
char* Insert3="');";

char* Insert=new
char[strlen(Insert1)+strlen(chash)+strlen(Insert2)+strlen(url)+strlen(Insert3)];
strcpy( Insert, Insert1);
strcat( Insert, chash);
strcat( Insert, Insert2);
strcat( Insert, url);
strcat( Insert, Insert3);
if (mysql_query(&mysql,Insert)) {
cerr << "Cannot insert into sep_hashtable : "
<< strerror(errno) << endl;
exit(1);
}
}

I can't find out why I'm getting this segfault error...can you help me
a bit?
 
J

Jakob Bieling

Hello!!
I'm studying c++ and I'm trying to get a little piece of code working,
but I'm getting a segfault with strlen here:

void tabhash::set (url *U) {
uint hash = U->hashCode();
char* url = U->giveUrl();
char* chash = (char*)hash;

Why are you casting an unsigned int to a char*? A cast is not a
lexical conversion, which you have probably intended. But then I do not
know how to interpret the return value of url::hashCode. But I doubt it
is meant to be casted to a char*.

hth
 
M

Martin Steen

char* Insert=new
char[strlen(Insert1)+strlen(chash)+strlen(Insert2)+strlen(url)+strlen(Insert3)];

Remember that in C and C++ a string is zero-terminated, so you must make
your stringbuffer large enough:

char* Insert = new char[LengthOffAllStrings + 1];

That "+ 1" is important..

Best regards, Martin
 
S

SirMike

Dnia 28 Sep 2006 02:58:51 -0700, (e-mail address removed) napisa³(a):
I'm studying c++ and I'm trying to get a little piece of code working,

Are you sure it's c++? This code doesn't show it.
Use i.e. std::string or std::stringstream if you are about to write good
c++ code.
char* Insert1="INSERT INTO sep_hashtable VALUES (";
char* Insert2=",0,'";
char* Insert3="');";

WTF? Don't do that. That's why you have segfault.
If you still want to use C style strings try:

char Insert1[] = {"abcd"};

or allocate some memory before writing to the pointer:

char *Insert1 = new char[BUFFER_SIZE];
strcpy(Insert1, "abcd"); // BE CAREFUL - DO NOT PUT longer string than the
buffer size
 
J

Jacek Dziedzic

Hello!!
I'm studying c++ and I'm trying to get a little piece of code working,
but I'm getting a segfault with strlen here:

void tabhash::set (url *U) {
uint hash = U->hashCode();
char* url = U->giveUrl();
char* chash = (char*)hash;

char* Insert1="INSERT INTO sep_hashtable VALUES (";
char* Insert2=",0,'";
char* Insert3="');";

char* Insert=new
char[strlen(Insert1)+strlen(chash)+strlen(Insert2)+strlen(url)+strlen(Insert3)];

Shouldn't this buffer be bigger to allow for the terminating '\0'?
strcpy( Insert, Insert1);
strcat( Insert, chash);
strcat( Insert, Insert2);
strcat( Insert, url);
strcat( Insert, Insert3);
if (mysql_query(&mysql,Insert)) {
cerr << "Cannot insert into sep_hashtable : "
<< strerror(errno) << endl;
exit(1);
}
}

I can't find out why I'm getting this segfault error...can you help me
a bit?

Anyway, that's what dealing with C-style strings usually brings
about -- a lot of strcpy()'s, strcat()'s and buffer overruns.
Consider using std::strings, they are way safer and can be
concatenated like

string Insert = Insert1 + Insert2 + Insert3;

while automatically growing to accommodate their contents.

HTH,
- J.
 
J

Jacek Dziedzic

SirMike said:
Dnia 28 Sep 2006 02:58:51 -0700, (e-mail address removed) napisa³(a):




Are you sure it's c++? This code doesn't show it.
Use i.e. std::string or std::stringstream if you are about to write good
c++ code.

This I agree with.
WTF? Don't do that. That's why you have segfault.

But not because of this? These are well formed
C-style string literals. They are fine in themselves,
except that they cannot be written to, right?
If you still want to use C style strings try:

char Insert1[] = {"abcd"};

or allocate some memory before writing to the pointer:

char *Insert1 = new char[BUFFER_SIZE];
strcpy(Insert1, "abcd"); // BE CAREFUL - DO NOT PUT longer string than the
buffer size

... or rather "longer string than buffer size minus one".

- J.
 
E

Eberhard Schefold

Jacek said:
But not because of this? These are well formed
C-style string literals. They are fine in themselves,
except that they cannot be written to, right?

They should be declared const, then the compiler will be able to help
you. The standard still allows non-const for reasons of C compatibility,
but this is deprecated.
 
S

SirMike

Dnia Thu, 28 Sep 2006 13:57:14 +0200, Jacek Dziedzic napisa³(a):
But not because of this? These are well formed
C-style string literals. They are fine in themselves,
except that they cannot be written to, right?

You're right. I only tried to emphasize that the whole code was wrong ;)
... or rather "longer string than buffer size minus one".

Exactly.
 
B

Bart

Hello!!
I'm studying c++ and I'm trying to get a little piece of code working,
but I'm getting a segfault with strlen here:

Your first problem is that you're not really using C++. You're just
using C++ as a better C. In C++ a much better way would be something
like the following:

#include <sstream>
....
std::stringstream stream;
stream
<< "INSERT INTO seb_hashtable VALUES ("
<< hashcode
<< ",0,'"
<< url
<< "');"
<< std::flush;
my_database.execute(stream.str());

See how easy? No need to manipulate char arrays and getting segfaults
for weird reasons.

You also have another potential problem too, but it's off-topic. Google
"SQL injection" for more info.

Regards,
Bart.
 
T

tragomaskhalos

char* Insert=new
char[strlen(Insert1)+strlen(chash)+strlen(Insert2)+strlen(url)+strlen(Insert3)];
strcpy( Insert, Insert1);
strcat( Insert, chash);
strcat( Insert, Insert2);
strcat( Insert, url);
strcat( Insert, Insert3);

I can't find out why I'm getting this segfault error...can you help me
a bit?

You are only allocating enough memory in Insert for the characters
you're putting in there, you need to add one more for the null
terminator, ie:
char* Insert = new char[strlen(Insert1)+...+strlen(Insert3) /** NB**/ +
1];

But anyway, all those strcats are a very brain-damaged way of achieving
what you want. There are better ways of achieving this in C, but in C++
you should be using std::string and std::stringstream. Look:

void tabhash::set (url *U) {
std::eek:stringstream os;
os << "INSERT INTO sep_hashtable VALUES ("
<< U->hashCode()
<< ",0,"
<< U->giveUrl()
<< ");"
;
if (mysql_query(&mysql, os.str().c_str())) {
cerr << "Cannot insert into sep_hashtable : "
<< strerror(errno) << endl;
exit(1);
}
}

It's quite a bit cleaner, no ?
 
R

Ron Natalie

Martin said:
char* Insert=new
char[strlen(Insert1)+strlen(chash)+strlen(Insert2)+strlen(url)+strlen(Insert3)];

Remember that in C and C++ a string is zero-terminated, so you must make
your stringbuffer large enough:

A C++ string is NOT necessarily null terminated.
It may contain nulls or not at any position.

It's only the use of char* as a defacto C-string that is so encumbered.
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top