By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,538 Members | 890 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,538 IT Pros & Developers. It's quick & easy.

strcat implementation?

P: n/a
Never mind my last post about pointer subtraction, I traced the code and
found the offender to be strcat.

char call[] = "del ";
system(strcat(strcat(call, del->table_name), ".tab"));

After this line, trying to dereference del results in page faults or
garbage. This makes me wonder how strcat is implemented, in terms of what it
actually does with the arguments. Seems like it actually moves the pointer.
Anyone know?
Nov 14 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Kevin C. wrote:
Never mind my last post about pointer subtraction, I traced the code and
found the offender to be strcat.

char call[] = "del ";
system(strcat(strcat(call, del->table_name), ".tab"));

You have declared call[] as an array of 5 chars; your strcat call has
written beyond the array so anything is possible.

Nov 14 '05 #2

P: n/a
On Fri, 07 May 2004 06:56:56 GMT, "Kevin C." <no****@fake.com> wrote:
Never mind my last post about pointer subtraction, I traced the code and
found the offender to be strcat.

char call[] = "del ";
system(strcat(strcat(call, del->table_name), ".tab"));

After this line, trying to dereference del results in page faults or
garbage. This makes me wonder how strcat is implemented, in terms of what it
actually does with the arguments. Seems like it actually moves the pointer.
Anyone know?


In addition to the other comments, if you don't know much about
pointers and arrays (and it seems you don't), then you might find it
easier to use the string class from the <string> header. e.g.

std::string call = "del ";
call += del->table_name;
call += ".tab";

There are no memory management issues to be concerned with with
std::string - it handles its own memory allocation, freeing the memory
when the string goes out of scope. That will be slower than the array
approach, but this is only a concern in a tight inner loop generally.

Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Nov 14 '05 #3

P: n/a
"Kevin C." <no****@fake.com> wrote in message news:<Yq****************@newssvr27.news.prodigy.co m>...
Never mind my last post about pointer subtraction, I traced the code and
found the offender to be strcat.

char call[] = "del ";
system(strcat(strcat(call, del->table_name), ".tab"));

After this line, trying to dereference del results in page faults or
garbage. This makes me wonder how strcat is implemented, in terms of what it
actually does with the arguments. Seems like it actually moves the pointer.
Anyone know?


The array call is allocated 5 bytes above ('d' 'e' 'l' ' ' '\0'). Any
attempt
to call strcat with it as the target will overwrite its array
boundries, unless you are attempting to append the empty string.

You could try to fix this as a hack by having
char call[100] = "del ";
Assuming that 100 will always hold what you need. Sadly, such
assumptions turn out to be right only until they are not. Maybe the
assumption was right when the code was written, etc. The correct way
to fix it is to figure out how much room you need for the 3 strings
you are putting together (not forgetting to add 1 for the terminating
NUL), dynamically allocate it, put it all together, and
issue your system command.

const char *fmt = "del %s.tab";
/* allocates 1 byte more than needed. whatever */
char *syscmd = malloc(strlen(fmt) + strlen(del->table_name) + 1);

if (syscmd == NULL) {
exit(EXIT_FAILURE);
}
else {
sprintf(syscmd, fmt, del->table_name);
system(syscmd);
free(syscmd);
}
Nov 14 '05 #4

P: n/a
On Fri, 7 May 2004, Kevin C. wrote:
Never mind my last post about pointer subtraction, I traced the code and
found the offender to be strcat.

char call[] = "del ";
system(strcat(strcat(call, del->table_name), ".tab"));

After this line, trying to dereference del results in page faults or
garbage. This makes me wonder how strcat is implemented, in terms of what it
actually does with the arguments. Seems like it actually moves the pointer.
Anyone know?


You are over-thinking this. Just read the definition of strcat. You have
declared the array call to be 5 characters long. The function strcat will
store everything in the call array. If the resulting string is greater
than 5 characters (and it is) then you are going to have undefined
behaviour. This is true for 100% of the implementations of strcat. You
don't need to know how your compiler has implemented strcat to know this.

Try:

char *call;
char tmp1[] = "del ";
char tmp2[] = ".tab";
int len = sizeof tmp1 + sizeof tmp2 + strlen(del->table_name);

if((call = malloc(len)) == NULL) exit(EXIT_FAILURE);
sprintf(call, "%s%s%s", tmp1, del->table_name, tmp2);
system(call);

--
Send e-mail to: darrell at cs dot toronto dot edu
Don't send e-mail to vi************@whitehouse.gov
Nov 14 '05 #5

P: n/a
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

tom_usenet wrote:
| On Fri, 07 May 2004 06:56:56 GMT, "Kevin C." <no****@fake.com> wrote:
|
|
|>Never mind my last post about pointer subtraction, I traced the code and
|>found the offender to be strcat.
|>
|>char call[] = "del ";
|>system(strcat(strcat(call, del->table_name), ".tab"));
|>
|>After this line, trying to dereference del results in page faults or
|>garbage. This makes me wonder how strcat is implemented, in terms of
what it
|>actually does with the arguments. Seems like it actually moves the
pointer.
|>Anyone know?
|
|
| In addition to the other comments, if you don't know much about
| pointers and arrays (and it seems you don't), then you might find it
| easier to use the string class from the <string> header. e.g.
|
| std::string call = "del ";
| call += del->table_name;
| call += ".tab";
|
| There are no memory management issues to be concerned with with
| std::string - it handles its own memory allocation, freeing the memory
| when the string goes out of scope. That will be slower than the array
| approach, but this is only a concern in a tight inner loop generally.
|
| Tom

Ummmm, doesn't work in C.

Ross
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFAm6q99bR4xmappRARAgI9AKCW55sbN5ZHcETo4DE7tO N7mp9uwACfQJ2/
KhsDGc+zvbyMtNboClOiRf8=
=bdRS
-----END PGP SIGNATURE-----
Nov 14 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.