Array initialisation

K

Koster

Just a quickie: I heard that arrays declared in the global scope are
automatically initialised with a block of zeros. To help with making my C
source compatible with multiple compilers, I'd like to know if this is a proper
ANSI-C thing or just another C++ quirk that only confuses people, if it's true
at all.

Thanks for your time,
Koster.
 
R

Russell Hanneken

Koster said:
I heard that arrays declared in the global scope are automatically
initialised with a block of zeros. To help with making my C source
compatible with multiple compilers, I'd like to know if this is a proper
ANSI-C thing or just another C++ quirk that only confuses people, if it's
true at all.

It's true if the objects stored in the array are of arithmetic type (i.e.,
integer or floating point), or are aggregates (structs or arrays) of
arithmetic types. Every arithmetic type object is given a value of 0--which
doesn't necessarily mean every bit is set to 0, since there's no guarantee
that 0 is represented by all 0 bits.

There's an analogous rule for static storage pointers, which by default are
initialized to null pointers. For unions, the first named member is
initialized according to the aforementioned rules.

I'm going by the C99 standard (section 6.7.8, paragraph 10). I'm pretty
sure the rules are the same in the old standard.

Regards,

Russell Hanneken
(e-mail address removed)
 
K

Kevin Easton

Koster said:
Just a quickie: I heard that arrays declared in the global scope are
automatically initialised with a block of zeros. To help with making my C
source compatible with multiple compilers, I'd like to know if this is a proper
ANSI-C thing or just another C++ quirk that only confuses people, if it's true
at all.

Any object with static storage duration, if it doesn't have an explicit
initialiser, is fully initialised with zeroes of the appropriate type
(plain 0s for integers, 0.0s for floating point and NULLs for pointers).

All objects defined at file scope have static storage duration, and so
do objects defined at block scope with the "static" storage class
modifier.

- Kevin.
 
K

Koster

Thanks. I didn't know the bit about pointers or structs either, I guess I'm
just your typical self-taught dabbler under the illusion that he knows what he's
doing, when in fact there's so much more to know. I'll try to get my hands on
those standards specifications for myself, for next time.

In the meantime, I now have a question about the appropriateness of calloc.
Consider an array of pointers to structs which need to be allocated space on the
heap, for example:

typedef struct myStruct *PMYSTRUCT;
struct myStruct
{
int i;
int j;
...etc...
}

PMYSTRUCT myArray[10];

While I know I can point and allocate each manually my looping mallocs, I wonder
if calloc will do what I want. Will executing "myArray = calloc(10,
sizeof(myStruct));" allocate 10 myStructs somewhere on the heap and put pointers
to each one in the myArray array, or will it allocate the myStructs and point
myArray[0] to it, thereby making myArray[1] point somewhere inside the 1st
myStruct and messing up everything?

I hope that's clear enough,
Koster.



|
|Just a quickie: I heard that arrays declared in the global scope are
|automatically initialised with a block of zeros. To help with making my C
|source compatible with multiple compilers, I'd like to know if this is a proper
|ANSI-C thing or just another C++ quirk that only confuses people, if it's true
|at all.
|
|Thanks for your time,
|Koster.
|

|
|It's true if the objects stored in the array are of arithmetic type (i.e.,
|integer or floating point), or are aggregates (structs or arrays) of
|arithmetic types. Every arithmetic type object is given a value of 0--which
|doesn't necessarily mean every bit is set to 0, since there's no guarantee
|that 0 is represented by all 0 bits.
|
|There's an analogous rule for static storage pointers, which by default are
|initialized to null pointers. For unions, the first named member is
|initialized according to the aforementioned rules.
|
|I'm going by the C99 standard (section 6.7.8, paragraph 10). I'm pretty
|sure the rules are the same in the old standard.
|
|Regards,
|
|Russell Hanneken
|[email protected]
|

|
|Any object with static storage duration, if it doesn't have an explicit
|initialiser, is fully initialised with zeroes of the appropriate type
|(plain 0s for integers, 0.0s for floating point and NULLs for pointers).
|
|All objects defined at file scope have static storage duration, and so
|do objects defined at block scope with the "static" storage class
|modifier.
|
| - Kevin.
|
 
J

Joe Wright

Koster said:
Thanks. I didn't know the bit about pointers or structs either, I guess I'm
just your typical self-taught dabbler under the illusion that he knows what he's
doing, when in fact there's so much more to know. I'll try to get my hands on
those standards specifications for myself, for next time.

In the meantime, I now have a question about the appropriateness of calloc.
Consider an array of pointers to structs which need to be allocated space on the
heap, for example:

typedef struct myStruct *PMYSTRUCT;
struct myStruct
{
int i;
int j;
...etc...
}

PMYSTRUCT myArray[10];

While I know I can point and allocate each manually my looping mallocs, I wonder
if calloc will do what I want. Will executing "myArray = calloc(10,
sizeof(myStruct));" allocate 10 myStructs somewhere on the heap and put pointers
to each one in the myArray array, or will it allocate the myStructs and point
myArray[0] to it, thereby making myArray[1] point somewhere inside the 1st
myStruct and messing up everything?

I hope that's clear enough,
Koster.
Your example is a little confusing to me and maybe to you. First I never
typedef a pointer. That hides a significant aspect of a variable and I
just don't do it. Stick with me here for a minute..

#define M 5
#define N 10
typedef struct myStruct {
int i;
int j;
int etc;
struct myStruct *next;
} myStruct;

We now have a User Defined Type. You can make (define) an array of these
sturctures by simply declaring it at file scope.

myStruct myArray[N];

Doing the same thing dynamically, presumably at block scope..

myStruct *dyArray;
dyArray = calloc(N, sizeof *dyArray);

We now have two similar things but note that myArray has array type and
dyArray has pointer type. But myArray[2] is a structure of type myStruct
and dyArray[2] is a structure of type myStruct.

Your reference to 'looping mallocs' is what really got my attention.
That's what you do to simulate a 2D array with pointers. Maybe like
this..

int i;
myStruct **d2Array; /* pointer to pointer to myStruct */
d2Array = malloc(M * sizeof *d2Array);
for (i = 0; i < M; ++i)
d2Array = calloc(N, sizeof **d2Array);

This would give us something like myStruct d2Array[5][10] to play with.
Is that what you meant?
 

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,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top