char array not terminated with \0

A

Anders Christensen

Hi.
Suppose str is defined as follows
char str[12] = "012345678901";

Is it wrong to use functions such as
printf("%s",str)
strcmp(str2,str)
strcpy(dest,str)

(since str is an array of chars without the teminating \0)?
What could the consequence be?

../Anders
 
A

Artie Gold

Anders said:
Hi.
Suppose str is defined as follows
char str[12] = "012345678901";

Is it wrong to use functions such as
printf("%s",str)
strcmp(str2,str)
strcpy(dest,str)

Yes. After all, where would it stop?
(since str is an array of chars without the teminating \0)?
What could the consequence be?

As it invokes undefined behavior, the consequence could be *anything*.
And if you happen to be running a Death Station 9000...

;-)

HTH,
--ag
 
M

Martin Ambuhl

Anders said:
Hi.
Suppose str is defined as follows
char str[12] = "012345678901";

Is it wrong to use functions such as
printf("%s",str)
strcmp(str2,str)
strcpy(dest,str)
Yes.

(since str is an array of chars without the teminating \0)?
Right.

What could the consequence be?

Overrunning the buffer while those functions look for the '\0', causing
rhinodaemons.
 
A

Artie Gold

Martin said:
Anders said:
Hi.
Suppose str is defined as follows
char str[12] = "012345678901";

Is it wrong to use functions such as
printf("%s",str)
strcmp(str2,str)
strcpy(dest,str)

Yes.

(since str is an array of chars without the teminating \0)?

Right.

What could the consequence be?


Overrunning the buffer while those functions look for the '\0', causing
rhinodaemons.
Demons, dammit, *demons*!!!

"Daemons" are OT here.

--ag
 
C

Chris Torek

[given an array of "char" that does not have a terminating '\0', i.e.,
is not a C string...]
Is it wrong to use functions such as
printf("%s",str)
strcmp(str2,str)
strcpy(dest,str)

(since str is an array of chars without the teminating \0)?

As several others have said, yes, all three of these calls look for
the terminating '\0', which -- since there is none in the array --
triggers undefined behavior. The first call is fixable, however:
since we know that "str" -- not such a good name, as it is not a
C string -- ends after 12 "char"s, we can use:

printf("%.12s", str);

or (because it is an array, so that sizeof works):

printf("%.*s", (int)sizeof str, str);

(Note that this second call would not work if str were a pointer
pointing to this not-a-C-string 12-character array, rather than
the actual array name itself. In that case, you would get
sizeof(char *) instead of sizeof(char [12]).)

All of this means that if printf() is implemented in C, its "%s"
handler must not use strlen() if a precision has been specified.
I noticed and fixed this bug in the printf() that Keith Bostic and
I coded up for 4.4BSD. We ended up with code of the form:

case 's':
s = va_arg(ap, char *);
if (flags & PREC) { /* e.g., %.10s, %.*s */
p = memchr(s, '\0', precision);
len = p ? p - s : precision;
} else
len = strlen(s);
/*
* then output no more than 'len' bytes from the area
* pointed to by 's', obeying field-width and left- and
* right-adjustment and so on, so that, e.g., %-100.10s
* and %30s work correctly.
*/
 
A

Anders Christensen

Thanks for your answers!

Will strcpy(str,"hardcoded") end up with
str = "hardcoded\001"
or
str = "hardcoded201"

or ... ?
 
K

Keith Thompson

Anders Christensen said:
Thanks for your answers!

Will strcpy(str,"hardcoded") end up with
str = "hardcoded\001"
or
str = "hardcoded201"

or ... ?

Please provide some context. In your original article, you
wrote:

char str[12] = "012345678901";

I'll assume that same declaration still applies.

strcpy(str, "hardcoded");

will copy the characters 'h','a','r','d','c','o','d','e','d','\0' into
str at positions 0 through 9, leaving the '0' and '1' in positions 10
and 11. The result will be as if you had written:

char str[12] = "hardcoded\001";

Any function that deals with strings (strcmp, printf, etc.) will of
course ignore anything after the '\0' character; for most purposes,
the value of str is just "hardcoded".
 
J

Joe Wright

Anders said:
Thanks for your answers!

Will strcpy(str,"hardcoded") end up with
str = "hardcoded\001"
or
str = "hardcoded201"

or ... ?
Did you read the answers? Your original..

char str[12] = "012345678901";

...defines str an array 12 of char without a terminating '\0'. Not a
string! The literal "hardcoded" is an array 10 of char and includes
the '\0' at the end. After executing..

strcpy(str,"hardcoded");

...I would expect that the first 10 elements of str are in fact
"hardcoded" and that str[10] is '0' and str[11] is '1'.

Note that while (sizeof str) remains 12, strlen(str) is now 9.
 
P

Peter Nilsson

Keith said:
Anders Christensen said:
Thanks for your answers!

Will strcpy(str,"hardcoded") end up with
str = "hardcoded\001"
or
str = "hardcoded201"

or ... ?

Please provide some context. In your original article, you
wrote:

char str[12] = "012345678901";

I'll assume that same declaration still applies.

strcpy(str, "hardcoded");

will copy the characters 'h','a','r','d','c','o','d','e','d','\0' into
str at positions 0 through 9, leaving the '0' and '1' in positions 10
and 11. The result will be as if you had written:

char str[12] = "hardcoded\001";

Not quite. An octal constant can be up to three octal digits long, so
\001 is actually a single byte with the value 1. You would need
something like...

char str[12] = "hardcoded\0""01";
 
J

James McIninch

<posted & mailed>

Anders said:
Hi.
Suppose str is defined as follows
char str[12] = "012345678901";

Is it wrong to use functions such as
printf("%s",str)
strcmp(str2,str)
strcpy(dest,str)

(since str is an array of chars without the teminating \0)?
What could the consequence be?

Those functions no where to stop reading the string by looking for the '\0'.
In the absence of it, they will sail past the end of the array. What
consequence is there? Who knows, the result is undefined. Typically either,
it will continue until a null is reached (whatever the next null in memory
is, or a memory fault will occur and something bad (crash) will result.
 
P

pete

Anders said:
Hi.
Suppose str is defined as follows
char str[12] = "012345678901";

Is it wrong to use functions such as
printf("%s",str)
strcmp(str2,str)
strcpy(dest,str)

It is wrong. str is not a pointer to a string.
As you can see from the description of strcpy in N869,
s2 must be a pointer to a string
in order for the effect of strcpy to be defined.

N869
7.21.2.3 The strcpy function
Synopsis
[#1]
#include <string.h>
char *strcpy(char * restrict s1,
const char * restrict s2);
Description
[#2] The strcpy function copies the string pointed to by s2
(including the terminating null character) into the array
pointed to by s1. If copying takes place between objects
that overlap, the behavior is undefined.
Returns
[#3] The strcpy function returns the value of s1.


N869 is here:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n869/
 
K

Keith Thompson

Peter Nilsson said:
Keith Thompson wrote: [...]
The result will be as if you had written:

char str[12] = "hardcoded\001";

Not quite. An octal constant can be up to three octal digits long, so
\001 is actually a single byte with the value 1. You would need
something like...

char str[12] = "hardcoded\0""01";

Oops, you're right. You could also write it as

char str[12] = "hardcoded\00001";

but that's not as clear.
 
T

thesushant

hi,
statements like char str[12]="012345678901", dont suffix "\0" after the
array of characters or strings on its own . or the programmer has to
give it explicitly??????????????

Chris said:
[given an array of "char" that does not have a terminating '\0', i.e.,
is not a C string...]
Is it wrong to use functions such as
printf("%s",str)
strcmp(str2,str)
strcpy(dest,str)

(since str is an array of chars without the teminating \0)?

As several others have said, yes, all three of these calls look for
the terminating '\0', which -- since there is none in the array --
triggers undefined behavior. The first call is fixable, however:
since we know that "str" -- not such a good name, as it is not a
C string -- ends after 12 "char"s, we can use:

printf("%.12s", str);

or (because it is an array, so that sizeof works):

printf("%.*s", (int)sizeof str, str);

(Note that this second call would not work if str were a pointer
pointing to this not-a-C-string 12-character array, rather than
the actual array name itself. In that case, you would get
sizeof(char *) instead of sizeof(char [12]).)

All of this means that if printf() is implemented in C, its "%s"
handler must not use strlen() if a precision has been specified.
I noticed and fixed this bug in the printf() that Keith Bostic and
I coded up for 4.4BSD. We ended up with code of the form:

case 's':
s = va_arg(ap, char *);
if (flags & PREC) { /* e.g., %.10s, %.*s */
p = memchr(s, '\0', precision);
len = p ? p - s : precision;
} else
len = strlen(s);
/*
* then output no more than 'len' bytes from the area
* pointed to by 's', obeying field-width and left- and
* right-adjustment and so on, so that, e.g., %-100.10s
* and %30s work correctly.
*/
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to
spammers.
 
A

Artie Gold

hi,
statements like char str[12]="012345678901", dont suffix "\0" after the
array of characters or strings on its own . or the programmer has to
give it explicitly??????????????
Don't top post. I've snipped the original message, as yours provides
enough context.

The issue in the definition above is that the array `str' is declared to
have sufficient room for only 12 chars; the '\0' would be appended *if
there was room for it*.

HTH,
--ag
 
C

Chris Croughton

Anders Christensen said:
Thanks for your answers!

Will strcpy(str,"hardcoded") end up with
str = "hardcoded\001"
or
str = "hardcoded201"

or ... ?

Please provide some context. In your original article, you
wrote:

char str[12] = "012345678901";

I'll assume that same declaration still applies.

strcpy(str, "hardcoded");

will copy the characters 'h','a','r','d','c','o','d','e','d','\0' into
str at positions 0 through 9, leaving the '0' and '1' in positions 10
and 11. The result will be as if you had written:

char str[12] = "hardcoded\001";

No, it won't, that would cause it to contain

'h', 'a', 'r', 'd', 'c', 'o', 'd', 'e', 'd', '\001', '\0', '\0'

I suspect you meant:

char str[12] = "hardcoded\00001";

Chris C
 
M

Mike Wahler

Artie Gold said:
hi,
statements like char str[12]="012345678901", dont suffix "\0" after the
array of characters or strings on its own . or the programmer has to
give it explicitly??????????????
Don't top post. I've snipped the original message, as yours provides
enough context.

The issue in the definition above is that the array `str' is declared to
have sufficient room for only 12 chars; the '\0' would be appended *if
there was room for it*.

For completeness:

Also, a '\0' would be appended if the size were computed
by the compiler, as happens when no size is explicitly specified:

char str[] = "abc"; /* array size is 4 */

-Mike
 
K

Keith Thompson

Chris Croughton said:
The result will be as if you had written:

char str[12] = "hardcoded\001";

No, it won't, that would cause it to contain

'h', 'a', 'r', 'd', 'c', 'o', 'd', 'e', 'd', '\001', '\0', '\0'

I suspect you meant:

char str[12] = "hardcoded\00001";

Quite correct, thanks.
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top