Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

does c++ initialize char arrays with '\0's

73 views
Skip to first unread message

G G

unread,
Jun 8, 2019, 7:58:59 PM6/8/19
to
i'm just wondering if i got lucky and the
cout << "Length of string in charr before input: "
<< strlen(charr) << endl;

return a 0, zero, because '\0' happened to be the first char in the
array charr ?

thanks.
---------------------------------------------------------
program from: Stephen Prada C++ Primer Plus p.137

// strtype4.cpp -- line input

#include <iostream>
#include <string>
#include <cstring>

int main()
{
using namespace std;

char charr[20];
string str;

cout << "Length of string in charr before input: "
<< strlen(charr) << endl;

cout << "Length of string in str before input: "
<< str.size() << endl;

cout << "Enter a line of text:\n";

cin.getline(charr, 20);

cout << "You entered: " << charr << endl;

cout << "Enter another line of text:\n";
getline(cin, str);

cout << "You entered: " << str << endl;

cout << "Length of string in char after input: "
<< strlen(charr) << endl;

cout << "Length of string in str after input: "
<< str.size() << endl;

return 0;
}

Alf P. Steinbach

unread,
Jun 8, 2019, 8:53:54 PM6/8/19
to
On 09.06.2019 01:58, G G wrote:
> i'm just wondering if i got lucky and the
> cout << "Length of string in charr before input: "
> << strlen(charr) << endl;
>
> return a 0, zero, because '\0' happened to be the first char in the
> array charr ?

Yes. A not explicitly initialized local POD variable has indeterminate
value. In the case of byte type it's in practice OK to access the value,
but a string length function can easily go beyond the end of the array
and then the formal Undefined Behavior can become very manifest.


> thanks.
> ---------------------------------------------------------
> program from: Stephen Prada C++ Primer Plus p.137

Thanks, it's useful for readers to know which book it is.


> // strtype4.cpp -- line input
>
> #include <iostream>
> #include <string>
> #include <cstring>
>
> int main()
> {
> using namespace std;
>
> char charr[20];
> string str;
>
> cout << "Length of string in charr before input: "
> << strlen(charr) << endl;

This is UB. This may be the last statement that's executed, depending on
luck or not.


> cout << "Length of string in str before input: "
> << str.size() << endl;
>
> cout << "Enter a line of text:\n";
>
> cin.getline(charr, 20);

Using magic constants is an ungood practice. Should have used `sizeof`
here. If the book had been more modern, should have used C++17
`std::size`, or even more modern, should have used C++20 `std::ssize`. ;-)


> cout << "You entered: " << charr << endl;
>
> cout << "Enter another line of text:\n";
> getline(cin, str);
>
> cout << "You entered: " << str << endl;
>
> cout << "Length of string in char after input: "
> << strlen(charr) << endl;
>
> cout << "Length of string in str after input: "
> << str.size() << endl;
>
> return 0;

This statement is redundantly expressing the well known default.

> }


Cheers & hth.,

- Alf

Juha Nieminen

unread,
Jun 9, 2019, 6:22:43 AM6/9/19
to
G G <gdo...@gmail.com> wrote:
> char charr[20];

No. Static arrays of basic types are not initialized. They are not
guaranteed to contain any specific values. In order to initialize them
you have to say so explicitly:

char charr[20] = {};

This will make the entire array zero-initialized.

If you want to bypass zero-initializing *the entire* array, and only
would want the first value to be zero, the only way to do that is:

char charr[20];
charr[0] = 0;

(Note that "charr charr[20] = { 0 };" will zero-initialize the entire
array, not just the first value.)

Chris Vine

unread,
Jun 9, 2019, 9:45:36 AM6/9/19
to
On Sun, 9 Jun 2019 10:22:35 -0000 (UTC)
Juha Nieminen <nos...@thanks.invalid> wrote:
> G G <gdo...@gmail.com> wrote:
> > char charr[20];
>
> No. Static arrays of basic types are not initialized. They are not
> guaranteed to contain any specific values.

A slip of the keyboard: I think you meant that non-static arrays of
basic types are not initialized (static ones are zero initialized).

Keith Thompson

unread,
Jun 9, 2019, 3:08:09 PM6/9/19
to
G G <gdo...@gmail.com> writes:
> i'm just wondering if i got lucky and the
> cout << "Length of string in charr before input: "
> << strlen(charr) << endl;
>
> return a 0, zero, because '\0' happened to be the first char in the
> array charr ?
>
> thanks.
> ---------------------------------------------------------
> program from: Stephen Prada C++ Primer Plus p.137

(It's "Prata". Which edition?)

> // strtype4.cpp -- line input
>
> #include <iostream>
> #include <string>
> #include <cstring>
>
> int main()
> {
> using namespace std;
>
> char charr[20];
> string str;
>
> cout << "Length of string in charr before input: "
> << strlen(charr) << endl;
[...]
> return 0;
> }

No, you got *unlucky*, or rather Stephen Prata did.

charr is initialized with arbitrary garbage (I carefully avoided
the word "random"), so strlen(charr) has undefined behavior.

If charr[0] happens to contain a '\0', that means the program has a bug
that's going to be difficult to diagnose, and will probably show up at
the most inconvenient possible time (in this case, after the book has
been published).

Can you submit an error report to the publisher?

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */

Melzzzzz

unread,
Jun 9, 2019, 3:11:38 PM6/9/19
to
You mean, not initialized... interrestingly languages like D that
initialize variables before use, have hacks not to do that.


--
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi
bili naoruzani. -- Mladen Gogala

G G

unread,
Jun 9, 2019, 3:47:41 PM6/9/19
to
i should have made it clear that in the book, the run of the program does not
return 0. in the book the value was 27 and the author explained that content
is an uninitialized array are undefined and it probably stopped at 27 because it
just happened to have a '\0' at that location.

sorry i didn't make that clear. my thought was perhaps that C++17 or new had
made a change... or i just luckily had a '\0' at the beginning of that array and that's
why i got an zero, 0, for the length.

the book edition is the sixth edition.
i'm using clang-900.0.39.2

sorry for the confusion everyone

Melzzzzz

unread,
Jun 9, 2019, 4:49:22 PM6/9/19
to
Since accessing unitialized variable is undefined there is no point in
discussing further...
>
> the book edition is the sixth edition.
> i'm using clang-900.0.39.2
>
> sorry for the confusion everyone


Juha Nieminen

unread,
Jun 10, 2019, 1:57:17 AM6/10/19
to
I'm using the term "static array" to mean a C-style array allocated
on the stack with a compile-time size. I'm not using it to mean
"an array that uses the keyword 'static'."

In other words "static array" is in contrast with "dynamic array",
which is an array that has been dynamically allocated (eg. with 'new').
In this case, "static" is the opposite of "dynamic". It's completely
unrelated to the 'static' keyword.

What is the correct term for C-style arrays, if not static array?

Chris Vine

unread,
Jun 10, 2019, 6:08:12 AM6/10/19
to
On Mon, 10 Jun 2019 05:57:10 -0000 (UTC)
Juha Nieminen <nos...@thanks.invalid> wrote:
> Chris Vine <chris@cvine--nospam--.freeserve.co.uk> wrote:
> > On Sun, 9 Jun 2019 10:22:35 -0000 (UTC)
> > Juha Nieminen <nos...@thanks.invalid> wrote:
> >> G G <gdo...@gmail.com> wrote:
> >> > char charr[20];
> >>
> >> No. Static arrays of basic types are not initialized. They are not
> >> guaranteed to contain any specific values.
> >
> > A slip of the keyboard: I think you meant that non-static arrays of
> > basic types are not initialized (static ones are zero initialized).
>
> I'm using the term "static array" to mean a C-style array allocated
> on the stack with a compile-time size. I'm not using it to mean
> "an array that uses the keyword 'static'."
>
> In other words "static array" is in contrast with "dynamic array",
> which is an array that has been dynamically allocated (eg. with 'new').
> In this case, "static" is the opposite of "dynamic". It's completely
> unrelated to the 'static' keyword.

I would use the expression "stack-allocated array" or more accurately
"array with automatic storage duration" for those. However, that is
irrelevant to whether the array elements are initialized or not: if the
array elements are of built-in type, they will be uninitialized whether
the array is allocated by new (dynamically allocated) or it is a local
stack-allocated array.

"static array" has a particular meaning in C++ and it is best to stick
to it. Arrays with static storage duration, whether in function scope
or in namespace scope, _are_ statically initialized and therefore are
either constant initialized or if not zero initialized.

> What is the correct term for C-style arrays, if not static array?

Definitely not "static array". I would use "C-style array", or more
simply do what the C++ standard does and refer to them as an "array":
the standard uses the the word "array" as signifying a C-style array
unless the word is used in the context of class template array
(std::array). But as I say, this is orthogonal to the issue of whether
array elements are zero initialized or not.

Juha Nieminen

unread,
Jun 11, 2019, 2:12:23 AM6/11/19
to
Chris Vine <chris@cvine--nospam--.freeserve.co.uk> wrote:
>> In other words "static array" is in contrast with "dynamic array",
>> which is an array that has been dynamically allocated (eg. with 'new').
>> In this case, "static" is the opposite of "dynamic". It's completely
>> unrelated to the 'static' keyword.
>
> I would use the expression "stack-allocated array" or more accurately
> "array with automatic storage duration" for those.

Except that it doesn't cover all the use cases, such as:

struct S
{
int values[10];
};

That's also a static array (rather than a dynamic one), but it isn't
necessarily stack-allocated. (Whether it's "with automatic storage
duration" depends on your definition of that expression. In a way
it is, as it's automatically disposed of alongside the rest of the struct.
However, that expression is often used to mean pretty much "in block
scope", ie. "automatically destroyed when the block ends", which imples
that it's being used inside a function. I think that's what the keyword
"auto", short for "automatic storage duration", originally meant in C.)

>> What is the correct term for C-style arrays, if not static array?
>
> Definitely not "static array". I would use "C-style array", or more
> simply do what the C++ standard does and refer to them as an "array":
> the standard uses the the word "array" as signifying a C-style array
> unless the word is used in the context of class template array
> (std::array). But as I say, this is orthogonal to the issue of whether
> array elements are zero initialized or not.

The problem is that you can do a "int* array = new int[10];", and that's
also an array. How do you distinguish between the two? If the latter is
a dynamic array, what's the former?

Keith Thompson

unread,
Jun 11, 2019, 2:40:36 AM6/11/19
to
Juha Nieminen <nos...@thanks.invalid> writes:
> Chris Vine <chris@cvine--nospam--.freeserve.co.uk> wrote:
>>> In other words "static array" is in contrast with "dynamic array",
>>> which is an array that has been dynamically allocated (eg. with 'new').
>>> In this case, "static" is the opposite of "dynamic". It's completely
>>> unrelated to the 'static' keyword.
>>
>> I would use the expression "stack-allocated array" or more accurately
>> "array with automatic storage duration" for those.
>
> Except that it doesn't cover all the use cases, such as:
>
> struct S
> {
> int values[10];
> };
>
> That's also a static array (rather than a dynamic one), but it isn't
> necessarily stack-allocated.

The array "values" has the same storage duration as "struct S" object of
which it's a member. It has no storage duration by itself. If no
"struct S" object is ever created, there won't be a "values" object.

Since the word "static" has a defined meaning (a storage duration),
using it to mean something else is just going to cause confusion.
(I don't know what you mean by "dynamic" in this context.)

> (Whether it's "with automatic storage
> duration" depends on your definition of that expression. In a way
> it is, as it's automatically disposed of alongside the rest of the struct.
> However, that expression is often used to mean pretty much "in block
> scope", ie. "automatically destroyed when the block ends", which imples
> that it's being used inside a function. I think that's what the keyword
> "auto", short for "automatic storage duration", originally meant in C.)

Yes.

>>> What is the correct term for C-style arrays, if not static array?
>>
>> Definitely not "static array". I would use "C-style array", or more
>> simply do what the C++ standard does and refer to them as an "array":
>> the standard uses the the word "array" as signifying a C-style array
>> unless the word is used in the context of class template array
>> (std::array). But as I say, this is orthogonal to the issue of whether
>> array elements are zero initialized or not.
>
> The problem is that you can do a "int* array = new int[10];", and that's
> also an array. How do you distinguish between the two? If the latter is
> a dynamic array, what's the former?

The object "array" is of course a pointer object, not an array object.
Its storage duration depends on where it's defined. The anonymous
object created by the "new" is an array object with dynamic storage
duration.

Chris Vine

unread,
Jun 11, 2019, 5:44:25 AM6/11/19
to
On Tue, 11 Jun 2019 06:12:11 -0000 (UTC)
Juha Nieminen <nos...@thanks.invalid> wrote:
> Chris Vine <chris@cvine--nospam--.freeserve.co.uk> wrote:
> >> In other words "static array" is in contrast with "dynamic array",
> >> which is an array that has been dynamically allocated (eg. with 'new').
> >> In this case, "static" is the opposite of "dynamic". It's completely
> >> unrelated to the 'static' keyword.
> >
> > I would use the expression "stack-allocated array" or more accurately
> > "array with automatic storage duration" for those.
>
> Except that it doesn't cover all the use cases, such as:
>
> struct S
> {
> int values[10];
> };
>
> That's also a static array (rather than a dynamic one)
[snip]

No, you have your terminology wrong. In C++98/03 there were three
storage durations: automatic, dynamic and static. C++11 added a
fourth, thread storage duration, for thread local variables. A struct
of type S, and so its array member, could have any of those storage
durations, depending on how the struct is constructed. In the case of
automatic and dynamic allocation (that is, stack-allocated or allocated
with new), the array will not be zero initialized. In the case of a
static or thread local struct, it will be zero initialized.

> >> What is the correct term for C-style arrays, if not static array?
> >
> > Definitely not "static array". I would use "C-style array", or more
> > simply do what the C++ standard does and refer to them as an "array":
> > the standard uses the the word "array" as signifying a C-style array
> > unless the word is used in the context of class template array
> > (std::array). But as I say, this is orthogonal to the issue of whether
> > array elements are zero initialized or not.
>
> The problem is that you can do a "int* array = new int[10];", and that's
> also an array. How do you distinguish between the two? If the latter is
> a dynamic array, what's the former?

According to the C++ standard, one is an "array with dynamic storage
duration", and the other is an "array with automatic storage
duration". I don't follow your problem here.

In practice, you would call them a dynamically allocated array and a
stack allocated array respectively, and everyone would understand you.

Chris Vine

unread,
Jun 11, 2019, 6:30:52 AM6/11/19
to
This assumes that by "the former" you meant the array up-thread that
started this discussion, which was stack allocated. If by "the former"
you meant the array member of S appearing earlier in your post, I have
already dealt with that: it could have any storage duration.

James Kuyper

unread,
Jun 11, 2019, 8:51:28 AM6/11/19
to
On 6/11/19 2:12 AM, Juha Nieminen wrote:
> Chris Vine <chris@cvine--nospam--.freeserve.co.uk> wrote:
...
>> I would use the expression "stack-allocated array" or more accurately
>> "array with automatic storage duration" for those.
>
> Except that it doesn't cover all the use cases, such as:
>
> struct S
> {
> int values[10];
> };
>
> That's also a static array (rather than a dynamic one), but it isn't
> necessarily stack-allocated. (Whether it's "with automatic storage
> duration" depends on your definition of that expression.

No - it depends upon the standard's definition of that term:
"Block-scope variables not explicitly declared static, thread_local, or
extern have _automatic storage duration_." (6.7.3p1). The term
"automatic storage duration" is italicized, an ISO convention indicating
that this is not merely a statement which uses that term; this statement
constitutes the official definition of that term.

Objects of type S can have any storage duration: static, thread,
automatic, or dynamic, and the storage duration of the values array is
the same as the object in which it resides.

> ... In a way
> it is, as it's automatically disposed of alongside the rest of the struct.
> However, that expression is often used to mean pretty much "in block
> scope", ie. "automatically destroyed when the block ends", which imples
> that it's being used inside a function. I think that's what the keyword
> "auto", short for "automatic storage duration", originally meant in C.)

It still has that meaning in C. It's almost completely useless - it can
only be used at block scope, and is the default for block scope, so it
can always be removed, which is why C++ could get away with giving it a
new completely unrelated meaning.

The keyword "static" has three meanings in C:

1. When used at file scope, it can be used to give an identifier
internal linkage.

2. When used at block scope, it can give an object static storage duration.

3. A declaration of a function parameter as if it were an array actually
declares a pointer to the type of an element of that array. The length
given for that array used to be meaningless, and could be dropped.
Starting in C99, however, if that length is preceded by the keyword
static, it becomes undefined behavior to call that function with a
pointer, if there is any integer from 0 to the one less than the
declared length of that array, for which you cannot deference the result
of adding that integer to that pointer. In principle, no diagnostic is
required, because a compiler cannot always determine whether or not this
rule will be violated, making this seem like a pointless addition to the
language. However, it often is feasible to diagnose this problem, and
good quality implementations will do so when it is feasible.

C++ has the meanings 1 and 2, but not 3. However, it adds yet another
meaning: when applied to a member of a class, "static" indicates that
the member can be accessed without going though an object of the class type.

Because of that ambiguity, I strongly recommend against using "static"
on it's own as an adjective. Use "static storage duration", "internal
linkage", or "static member". I have not figured out a good way to refer
to identifiers declared using option 3.

Chris Vine

unread,
Jun 11, 2019, 11:02:42 AM6/11/19
to
On Tue, 11 Jun 2019 08:51:14 -0400
James Kuyper <james...@alumni.caltech.edu> wrote:
[snip]
> C++ has the meanings 1 and 2, but not 3. However, it adds yet another
> meaning: when applied to a member of a class, "static" indicates that
> the member can be accessed without going though an object of the class type.

I suppose that extension has some kind of logic, because any static data
member of a class will, if ODR-used, have to have static storage
allocated for it. But that doesn't particularly explain "static"
member functions, except by further extension (that term in particular
has nothing to do with a static function with internal linkage, your
meaning 1).

I would further argue that the word "static" has acquired a fifth
meaning in C++, in the sense of "resolvable at compile time". The
standard defines "static type" as "the type of an expression (6.9)
resulting from analysis of the program without considering execution
semantics", and defines "dynamic type" correspondingly. The same
sense seems to underlie static_cast and dynamic_cast, and in the way
some people describe the use of templates as providing "static
polymorphism". Although Juha's description of a C-style array
allocated on the stack as a "static array" is highly misleading and
will be misunderstood whenever he tries to use it to denote that, I can
sort of see what led him there (assuming "C-style" here means C89-style,
so not including C99 VLAs).

James Kuyper

unread,
Jun 11, 2019, 10:32:22 PM6/11/19
to
On 6/11/19 11:02 AM, Chris Vine wrote:
> On Tue, 11 Jun 2019 08:51:14 -0400
> James Kuyper <james...@alumni.caltech.edu> wrote:
> [snip]
>> C++ has the meanings 1 and 2, but not 3. However, it adds yet another
>> meaning: when applied to a member of a class, "static" indicates that
>> the member can be accessed without going though an object of the class type.
>
> I suppose that extension has some kind of logic, because any static data
> member of a class will, if ODR-used, have to have static storage
> allocated for it. But that doesn't particularly explain "static"
> member functions, except by further extension (that term in particular
> has nothing to do with a static function with internal linkage, your
> meaning 1).
>
> I would further argue that the word "static" has acquired a fifth
> meaning in C++, in the sense of "resolvable at compile time". The

I was talking about the meanings of the "static" keyword. The word
"static" itself does indeed have several additional meanings that don't
involve it's use as a keyword, which only adds to the potential for
confusion.
0 new messages