strcat and overwritten strings

C

cicalese

For starters, I am a C novice. I don't fully understand how strings
work. I am running on a linux box. I compile w/ gcc. I have a string
called 'myabqcommand' that is being overwritten when i use strcat() on
some unrelated strings.

For this code:

char *myabqcommand;

myabqcommand = strtok(x, "-");
printf("%s\n", myabqcommand);

char str2[4] = "cp ";
strcat(str2, ideck);
strcat(str2, ".inp ");
strcat(str2, myfiles);
strcat(str2, " /homecluster1/");
strcat(str2, uname);
printf("%s\n", str2);
system(str2);

//INCORRECT STRING
printf("%s\n", myabqcommand);



I get this output:


rsh cluster1 abaqus j=A user=new.f
cp A.inp new.f dir1.csv dir2.csv dir3.csv /homecluster1/user1
//RESULT OF INCORRECT STRING
dir3.csv /homecluster1/cicalese


I expected to get this output:


rsh cluster1 abaqus j=A user=new.f
cp A.inp new.f dir1.csv dir2.csv dir3.csv /homecluster1/user1
rsh cluster1 abaqus j=A user=new.f


Can anyone help? Thanks
 
K

Kenneth Brody

char str2[4] = "cp ";

Here, you create a char array "str2" consisting of 4 characters, and
you initialize it to the 4 characters 'c', 'p', ' ', and '\0';.
strcat(str2, ideck);
strcat(str2, ".inp ");
strcat(str2, myfiles);
strcat(str2, " /homecluster1/");
strcat(str2, uname);

Here, you do nasty things to the memory beyond the 4 characters that
you set aside for str2.

It's called "buffer overrun", and invokes undefined behavior. You
need to make sure that your buffer is large enough to hold the text
that you are going to store in it. One way would to use malloc(),
based on the combined length of all of the strings you are going
to concatenate into it. (Don't forget to free it when you're done
if you use that method.)

[...]

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:[email protected]>
 
P

Pedro Graca

For starters, I am a C novice. I don't fully understand how strings
work. I am running on a linux box. I compile w/ gcc. I have a string
called 'myabqcommand' that is being overwritten when i use strcat() on
some unrelated strings.

For this code:

char *myabqcommand;

myabqcommand = strtok(x, "-");
printf("%s\n", myabqcommand);

char str2[4] = "cp ";

"Map of memory" at this point

--------XXXX--------
^^^^
The X's mark the amount of memory reserved for str2 ('c', 'p', ' ', and
the terminating NUL).
What is to either side of that (if anything) is reserved for something
else.

strcat(str2, ideck);

--------XXXX--------
^^^^^
ideck

If ideck is not an empty sring, You've just tried to use memory that
you don't know exists (or maybe that is reserved for the Operating
System, or that signals demons to start oozing out of your nostrils).

<snip>


For a first newbie approach (I'm a newbie too) try reserving more space
for str2

#define MAXIMUM_STR2_LENGTH 2000

char str2[MAXIMUM_STR2_LENGTH] = "cp ";

if (strlen(str2) + strlen(ideck) < MAXIMUM_STR2_LENGTH) {
strcat(str2, ideck);
} else {
fprintf(stderr, "%d bytes isn't enough for the `myabqcommad'.\n",
MAXIMUM_STR2_LENGTH);
exit(EXIT_FAILURE);
}
 
F

Fred Kleinschmidt

For starters, I am a C novice. I don't fully understand how strings
work. I am running on a linux box. I compile w/ gcc. I have a string
called 'myabqcommand' that is being overwritten when i use strcat() on
some unrelated strings.

For this code:

char *myabqcommand;

myabqcommand = strtok(x, "-");
printf("%s\n", myabqcommand);

char str2[4] = "cp ";

You have specified storage for a maximum of 4 characters for variable str2.
strcat(str2, ideck);

What is ideck?
strcat(str2, ".inp ");

This will definitely overflow the 4 characters. It can clobber almost
anything.
strcat(str2, myfiles);
More writing into space you do not own.
strcat(str2, " /homecluster1/"); Same
strcat(str2, uname); Same
printf("%s\n", str2);
system(str2);
<snip>
 
D

Default User

For starters, I am a C novice. I don't fully understand how strings
work. I am running on a linux box. I compile w/ gcc. I have a string
called 'myabqcommand' that is being overwritten when i use strcat() on
some unrelated strings.
char str2[4] = "cp ";

So you allocated space for 4 characters, and used all four.
strcat(str2, ideck);
This overwrote the last (null) character, then started writing off into
some other memory.

At that point, you have undefined behavior. Don't do it. You have to
have enough memory allocated ahead of time for the new combined string.



Brian
 
S

stathis gotsis

Pedro Graca said:
For starters, I am a C novice. I don't fully understand how strings
work. I am running on a linux box. I compile w/ gcc. I have a string
called 'myabqcommand' that is being overwritten when i use strcat() on
some unrelated strings.

For this code:

char *myabqcommand;

myabqcommand = strtok(x, "-");
printf("%s\n", myabqcommand);

char str2[4] = "cp ";
For a first newbie approach (I'm a newbie too) try reserving more space
for str2

#define MAXIMUM_STR2_LENGTH 2000

char str2[MAXIMUM_STR2_LENGTH] = "cp ";

if (strlen(str2) + strlen(ideck) < MAXIMUM_STR2_LENGTH)

More correct would be:
if (strlen(str2) + strlen(ideck) +1 < MAXIMUM_STR2_LENGTH)remembering that
the newly created string will need to terminate with '\0'.
 
P

Pedro Graca

stathis said:
Pedro Graca said:
#define MAXIMUM_STR2_LENGTH 2000

char str2[MAXIMUM_STR2_LENGTH] = "cp ";

if (strlen(str2) + strlen(ideck) < MAXIMUM_STR2_LENGTH)

More correct would be:
if (strlen(str2) + strlen(ideck) +1 < MAXIMUM_STR2_LENGTH)remembering that
the newly created string will need to terminate with '\0'.

Why?

#define MAX_LEN 5

char c1[] = "12";
char c2[] = "42";
if (strlen(str2) + strlen(ideck) < MAX_LEN) { /* ok */ }
/* sizeof "1242" == 5 */


char c1[] = "123";
char c2[] = "42";
if (strlen(str2) + strlen(ideck) < MAX_LEN) { /* not ok */ }
/* sizeof "12342" == 6 */
 
S

stathis gotsis

Pedro Graca said:
stathis said:
Pedro Graca said:
#define MAXIMUM_STR2_LENGTH 2000

char str2[MAXIMUM_STR2_LENGTH] = "cp ";

if (strlen(str2) + strlen(ideck) < MAXIMUM_STR2_LENGTH)

More correct would be:
if (strlen(str2) + strlen(ideck) +1 < MAXIMUM_STR2_LENGTH)remembering that
the newly created string will need to terminate with '\0'.

Why?

#define MAX_LEN 5

char c1[] = "12";
char c2[] = "42";
if (strlen(str2) + strlen(ideck) < MAX_LEN) { /* ok */ }
/* sizeof "1242" == 5 */


char c1[] = "123";
char c2[] = "42";
if (strlen(str2) + strlen(ideck) < MAX_LEN) { /* not ok */ }
/* sizeof "12342" == 6 */

Sorry my mistake. i meant: strlen(str2)+strlen(ideck)+1<=MAX_LEN, which is
the same as your version.
 
B

Barry Schwarz

For starters, I am a C novice. I don't fully understand how strings
work. I am running on a linux box. I compile w/ gcc. I have a string
called 'myabqcommand' that is being overwritten when i use strcat() on
some unrelated strings.

For this code:

char *myabqcommand;

myabqcommand = strtok(x, "-");
printf("%s\n", myabqcommand);

char str2[4] = "cp ";
strcat(str2, ideck);
strcat(str2, ".inp ");
strcat(str2, myfiles);
strcat(str2, " /homecluster1/");
strcat(str2, uname);
printf("%s\n", str2);
system(str2);

//INCORRECT STRING
printf("%s\n", myabqcommand);



I get this output:


rsh cluster1 abaqus j=A user=new.f
cp A.inp new.f dir1.csv dir2.csv dir3.csv /homecluster1/user1
//RESULT OF INCORRECT STRING
dir3.csv /homecluster1/cicalese


I expected to get this output:


rsh cluster1 abaqus j=A user=new.f
cp A.inp new.f dir1.csv dir2.csv dir3.csv /homecluster1/user1
rsh cluster1 abaqus j=A user=new.f
Post a complete function that exhibits the unexpected behavior.


Remove del for email
 

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,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top