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

String and null character

P: n/a
Some questions about strings: this is the extracted piece of my test code:

/** **/

char *arry;
arry = malloc(30*sizeof(arry));

arry[0] = 'B';
arry[1] = 'S';
arry[2] = 'c';

/** **/

The questions are:

1. Now does the variable arry contain the null character immediately because
of malloc?

2. or I should append '0' at arry[3] ? (which in fact what I did next, but
when testing the compiler without '\0', it worked (??)

Because in both cases (whether I append '\0' or not), if I use the
functions atoi or any other string functions, the compiler
does not give warning or error message, what happened?

Thanks in advance
Nov 13 '05 #1
Share this Question
Share on Google+
13 Replies


P: n/a
"Chapman" <ch**@hotmail.com> wrote:
Some questions about strings: this is the extracted piece of my test code:

/** **/

char *arry;
arry = malloc(30*sizeof(arry)); You allocate memory to hold 30 pointers-to-character, which is obviously
not your intention; make this:

arry = malloc( 30 * sizeof *arry );

arry[0] = 'B';
arry[1] = 'S';
arry[2] = 'c';

/** **/

The questions are:

1. Now does the variable arry contain the null character immediately because
of malloc? No.

2. or I should append '0' at arry[3] ? If you intend to use it as a string: yes.
(which in fact what I did next, but
when testing the compiler without '\0', it worked (??) This was just (bad) luck; virtually *anything* could have happened.

Because in both cases (whether I append '\0' or not), if I use the
functions atoi or any other string functions, the compiler
does not give warning or error message, what happened?

The compiler cannot check something that gets allocated and altered at
run-time. You have to make sure your strings are '\0'-terminated.

Regards

Irrwahn
--
Close your eyes and press escape three times.
Nov 13 '05 #2

P: n/a

"Chapman" <ch**@hotmail.com> wrote in message
news:il********************@news-server.bigpond.net.au...
Some questions about strings: this is the extracted piece of my test code:

/** **/

char *arry;
arry = malloc(30*sizeof(arry));
If you want to allocate a buffer to hold a string, you should write

arry = malloc(30); /* This way is correct. "sizeof char" is defined as 1
byte, you don't need to use sizeof on this */

or

arry = malloc(30 * sizeof *arry) /* You should use sizeof on "*arry" (which
is a single char), not char* (which is a pointer. I think this is not what
you want, right ? ). Also, don't use "sizeof( variable )" , use "sizeof
variable" or "sizeof(variable type)" instead. */


arry[0] = 'B';
arry[1] = 'S';
arry[2] = 'c';

/** **/

The questions are:

1. Now does the variable arry contain the null character immediately because of malloc?
No. If you want to fill all the elements by zero after allocated, you can
consider "calloc"
2. or I should append '0' at arry[3] ?
Yes.

(which in fact what I did next, but when testing the compiler without '\0', it worked (??)

Don't believe this, you are just lucky.
Because in both cases (whether I append '\0' or not), if I use the
functions atoi or any other string functions, the compiler
does not give warning or error message, what happened?


Why should it give warning or error ?
--
Jeff
-je6543 at yahoo.com
Nov 13 '05 #3

P: n/a
"Chapman" <ch**@hotmail.com> wrote in message news:<il********************@news-server.bigpond.net.au>...
Some questions about strings: this is the extracted piece of my test code:

/** **/

char *arry;
arry = malloc(30*sizeof(arry));
ITYM

arry = malloc (30 * sizeof *arry);

The type of arry is char*; the type of *arry is char.

arry[0] = 'B';
arry[1] = 'S';
arry[2] = 'c';

/** **/

The questions are:

1. Now does the variable arry contain the null character immediately because
of malloc?

No. malloc() does not initialize the allocated memory to any specific
value. Assume it contains garbage. If you need the memory to be
initialized to 0 when allocating it, use calloc().
2. or I should append '0' at arry[3] ? (which in fact what I did next, but
when testing the compiler without '\0', it worked (??)
Luck. The memory you allocated just happened to be zeroed out, but
you can't rely on that behavior.

Because in both cases (whether I append '\0' or not), if I use the
functions atoi or any other string functions, the compiler
does not give warning or error message, what happened?

Thanks in advance


The string functions will walk through memory starting at the point
you specify until they see a nul terminator (0). If you forget to put
a nul terminator in your buffer, the string functions will happily
read or write past it until they either find one or try to read or
write a protected or invalid memory address, causing a trap.

Either way, forgetting to append a nul terminator to a dynamically
allocated buffer is a condition that only occurs when the program is
run; your compiler can't warn you about something that it can't
predict.
Nov 13 '05 #4

P: n/a

"Jeff" <no*****@notexist.com> wrote in message
news:bk***********@news.hgc.com.hk...

"Chapman" <ch**@hotmail.com> wrote in message
news:il********************@news-server.bigpond.net.au...
Some questions about strings: this is the extracted piece of my test code:
/** **/

char *arry;
arry = malloc(30*sizeof(arry));
If you want to allocate a buffer to hold a string, you should write

arry = malloc(30); /* This way is correct. "sizeof char" is defined as 1
byte, you don't need to use sizeof on this */

or

arry = malloc(30 * sizeof *arry) /* You should use sizeof on "*arry"

(which is a single char), not char* (which is a pointer. I think this is not what you want, right ? ). Also, don't use "sizeof( variable )" , use "sizeof
variable" or "sizeof(variable type)" instead. */
Thanks for the explanation Jeff.
The questions are:

1. Now does the variable arry contain the null character immediately

because
of malloc?


No. If you want to fill all the elements by zero after allocated, you can
consider "calloc"
2. or I should append '0' at arry[3] ?


Yes.

(which in fact what I did next, but
when testing the compiler without '\0', it worked (??)


Don't believe this, you are just lucky.


I could not believe it either, and everytime I run the program without
appending the '\0', it was alright.
Something wrong with gcc ? Following the standard, I appended '\0', just
curious why it happened without warning.
It is not about being lucky, or probably the function definitions with gcc
is 'relaxed' about the '\0' ??
Because in both cases (whether I append '\0' or not), if I use the
functions atoi or any other string functions, the compiler
does not give warning or error message, what happened?


Why should it give warning or error ?


It should gave me error when I run it and the string did not have the '\0',
but it didn't
--
Jeff
-je6543 at yahoo.com

Nov 13 '05 #5

P: n/a

"Chapman" <ch**@yahoo.com> wrote in message

I could not believe it either, and everytime I run the program without
appending the '\0', it was alright.
Something wrong with gcc ? Following the standard, I appended '\0',
just curious why it happened without warning.
It is not about being lucky, or probably the function definitions with gcc
is 'relaxed' about the '\0' ??
String functions will generally fail if passed a non-NUL terminated string.

However it is quite common for garbage memory to contain a lot of zeroes,
and you must have just hit a zero. It's also possible that your version of
malloc() zeroes memory, however you can't rely on this behaviour.
It should gave me error when I run it and the string did not have the
'\0', but it didn't

The following code is OK

char *str = calloc(1,100);
str[0] = 'F';
str[1] = 'R';
str[2] = 'E';
str[3] = 'D';
printf("%s\n", str);

This is because calloc() is guaranteed to zero memory.

The compiler is not clever enough to distinguish between the function
calloc() and malloc(), and realise that in your case you are setting up a
string which is not NUL-terminated. This is because C is such a low-level
language - strings are just handled as arrays of bytes in memory.
Nov 13 '05 #6

P: n/a
"Malcolm" <ma*****@55bank.freeserve.co.uk> wrote:

"Chapman" <ch**@yahoo.com> wrote in message

I could not believe it either, and everytime I run the program without
appending the '\0', it was alright.
Something wrong with gcc ? Following the standard, I appended '\0',
just curious why it happened without warning.
It is not about being lucky, or probably the function definitions with gcc
is 'relaxed' about the '\0' ??

String functions will generally fail if passed a non-NUL terminated string.

^^^^^^^^^^^^^^^^^^^
Nit-pick: ... will generally invoke undefined behaviour ...

<SNIP>

Regards

Irrwahn
--
Close your eyes and press escape three times.
Nov 13 '05 #7

P: n/a
"Chapman" <ch**@yahoo.com> wrote in message news:<9m*********************@news-server.bigpond.net.au>...
"Jeff" <no*****@notexist.com> wrote in message
news:bk***********@news.hgc.com.hk...

"Chapman" <ch**@hotmail.com> wrote in message
news:il********************@news-server.bigpond.net.au...
Some questions about strings: this is the extracted piece of my test code:
/** **/

char *arry;
arry = malloc(30*sizeof(arry));


If you want to allocate a buffer to hold a string, you should write

arry = malloc(30); /* This way is correct. "sizeof char" is defined as 1
byte, you don't need to use sizeof on this */

or

arry = malloc(30 * sizeof *arry) /* You should use sizeof on "*arry"

(which
is a single char), not char* (which is a pointer. I think this is not

what
you want, right ? ). Also, don't use "sizeof( variable )" , use "sizeof
variable" or "sizeof(variable type)" instead. */

Thanks for the explanation Jeff.
The questions are:

1. Now does the variable arry contain the null character immediately because of malloc?


No. If you want to fill all the elements by zero after allocated, you can
consider "calloc"
2. or I should append '0' at arry[3] ?


Yes.

(which in fact what I did next, but
when testing the compiler without '\0', it worked (??)


Don't believe this, you are just lucky.


I could not believe it either, and everytime I run the program without
appending the '\0', it was alright.
Something wrong with gcc ? Following the standard, I appended '\0', just
curious why it happened without warning.
It is not about being lucky, or probably the function definitions with gcc
is 'relaxed' about the '\0' ??
Because in both cases (whether I append '\0' or not), if I use the
functions atoi or any other string functions, the compiler
does not give warning or error message, what happened?


Why should it give warning or error ?


It should gave me error when I run it and the string did not have the '\0',
but it didn't


You run it on some other platform it would possibly give you an error
eventhough the chances of having a runtime error are more than those
of a compile time error. It is as a matter of fact difficult to get to
know if you are setting or not setting the null character, consider
this

while ( some_condition )
{
c = getchar();
malloced_character_array [ i ] = c;
i += 1;
}

During complile time it is quite difficult to determine as to if what
the user would set the value to be.
BTW compiler is not supposed to give any error and I think I won't be
wrong if I could say that the compiler is not supposed to give error
even for a completly invalid program

even if you type garbage in your source file, it is quite unreasonable
but true that a compiler can give you a message of the form of

"succesfully built".
HTH
PS IIRC someone had a website which showed a missile heading back to
the carrier which shot them in case of program exhibiting a UB, can
anybody provide that link.

--

Imanpreet Singh Arora
imanpreet_arora AT yahoo DOT co DOT in
Nov 13 '05 #8

P: n/a
On Tue, 16 Sep 2003 00:55:30 +0200, Irrwahn Grausewitz
<ir*****@freenet.de> wrote in comp.lang.c:
"Malcolm" <ma*****@55bank.freeserve.co.uk> wrote:

"Chapman" <ch**@yahoo.com> wrote in message

I could not believe it either, and everytime I run the program without
appending the '\0', it was alright.
Something wrong with gcc ? Following the standard, I appended '\0',
just curious why it happened without warning.
It is not about being lucky, or probably the function definitions with gcc
is 'relaxed' about the '\0' ??
String functions will generally fail if passed a non-NUL terminated string.

^^^^^^^^^^^^^^^^^^^
Nit-pick: ... will generally invoke undefined behaviour ...

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Even more nit pick: will ALWAYS invoke undefined behavior, which
generally causes a program to fail.

<SNIP>

Regards

Irrwahn


--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
Nov 13 '05 #9

P: n/a
mi************@yahoo.com (Minti) wrote:

<SNIP>

BTW compiler is not supposed to give any error and I think I won't be
wrong if I could say that the compiler is not supposed to give error
even for a completly invalid program

even if you type garbage in your source file, it is quite unreasonable
but true that a compiler can give you a message of the form of

"succesfully built".

<SNIP>

Hmm, consider this quote from n843:

5.1.1.3 Diagnostics

[#1] A conforming implementation shall produce at least one
diagnostic message (identified in an implementation-defined
manner) if a preprocessing translation unit or translation
unit contains a violation of any syntax rule or constraint,
even if the behavior is also explicitly specified as
undefined or implementation-defined. Diagnostic messages
need not be produced in other circumstances.7)

[#2] EXAMPLE An implementation shall issue a diagnostic for
the translation unit:

char i;
int i;

because in those cases where wording in this International
Standard describes the behavior for a construct as being
both a constraint error and resulting in undefined behavior,
the constraint error shall be diagnosed.

[...]

Regards

Irrwahn
--
My opinions are not those of my ex-employer.
Nov 13 '05 #10

P: n/a
On Tue, 16 Sep 2003 01:59:45 GMT, in comp.lang.c , Jack Klein
<ja*******@spamcop.net> wrote:
On Tue, 16 Sep 2003 00:55:30 +0200, Irrwahn Grausewitz
<ir*****@freenet.de> wrote in comp.lang.c:
"Malcolm" <ma*****@55bank.freeserve.co.uk> wrote:
>>
>String functions will generally fail if passed a non-NUL terminated string.

^^^^^^^^^^^^^^^^^^^
Nit-pick: ... will generally invoke undefined behaviour ...

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Even more nit pick: will ALWAYS invoke undefined behavior, which
generally causes a program to fail.


super nitpick: which MAY cause a program to fail, or alternatively to
succeed by pure chance some of the time, or to merely seem to succeed
but in fact to be storing up trouble for later eg when demo'ing to a
client. The latter pair are in my experience by far the commonest.
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>
Nov 13 '05 #11

P: n/a

"Mark McIntyre" <ma**********@spamcop.net> wrote in message
super nitpick: which MAY cause a program to fail, or alternatively to
succeed by pure chance some of the time, or to merely seem to
succeed but in fact to be storing up trouble for later eg when demo'ing
to a client. The latter pair are in my experience by far the commonest.

We're talking about passing a string which is not NUL-terminated to a string
function, as opposed to passing a string which has been accidentally
terminated by a NUL (as the OP seemed to be finding).

A few functions, like strchr(), will succeed in some circumstances. Most,
like strlen(), will find it very difficult to produce "correct" results.
strlen() will probably charge through memory until it hits a zero byte,
which will either result in an incorrect answer or a segmentation fault.
Most string functions are similar.
If you have undefined behaviour, and the string functions seem to be working
OK, it is unlikely that you are passing non-NUL terminated strings to these
functions, and UB produces the expected results. It is probable that the
byte following the string happens to be zero.
Nov 13 '05 #12

P: n/a
Irrwahn Grausewitz <ir*****@freenet.de> wrote in message news:<3f********************************@4ax.com>. ..
mi************@yahoo.com (Minti) wrote:

<SNIP>

BTW compiler is not supposed to give any error and I think I won't be
wrong if I could say that the compiler is not supposed to give error
even for a completly invalid program

even if you type garbage in your source file, it is quite unreasonable
but true that a compiler can give you a message of the form of

"succesfully built".

<SNIP>

Hmm, consider this quote from n843:

5.1.1.3 Diagnostics

[#1] A conforming implementation shall produce at least one
diagnostic message (identified in an implementation-defined
manner) if a preprocessing translation unit or translation
unit contains a violation of any syntax rule or constraint,
even if the behavior is also explicitly specified as
undefined or implementation-defined. Diagnostic messages
need not be produced in other circumstances.7)

[#2] EXAMPLE An implementation shall issue a diagnostic for
the translation unit:

char i;
int i;

because in those cases where wording in this International
Standard describes the behavior for a construct as being
both a constraint error and resulting in undefined behavior,
the constraint error shall be diagnosed.

[...]


Thanks for correction.
Nov 13 '05 #13

P: n/a
mi************@yahoo.com (Minti) wrote in message news:<e8**************************@posting.google. com>...

.....
<snip>

PS IIRC someone had a website which showed a missile heading back to
the carrier which shot them in case of program exhibiting a UB, can
anybody provide that link.


http://dspace.dial.pipex.com/town/green/gfd34/art/

--
Imanpreet Singh Arora
imanpreet_arora AT yahoo DOT co DOT in
Nov 13 '05 #14

This discussion thread is closed

Replies have been disabled for this discussion.