NO

Author Topic: Array initialization error  (Read 6656 times)

Roda

  • Guest
Array initialization error
« on: July 20, 2013, 02:06:32 AM »
First, I am pretty new to programming. I have less than a year of experience and that is mostly in Python. I am following a book (Programming in C, by Stephan Kochan) to  learn C. I'm typing a simple program:
Code: [Select]
#include <stdio.h>
int main (void)
{
int values[10];
int index;

for (index = 0; index < 10; ++index)
printf("values[%i] = %i\n", index, values[index]);

return 0;
}
This should show all my elements initialized to 0 in C correct? But for some odd reason values[4] is initialized an integer. If I retype this code under different projects the value of values[4], and it is always values[4] for some reason, will change to a different integer. The only way the output shows all the values of the elements of the array as 0 is if I initialize all the elements in the array to 0 first. I have tried using the debugger but it really confuses me at the moment so I thought I'd post on this forum hoping that someone would have an explanation to why this is happening.

« Last Edit: July 20, 2013, 05:52:28 AM by Bitbeisser »

Offline Bitbeisser

  • Global Moderator
  • Member
  • *****
  • Posts: 772
Re: Array initialization error
« Reply #1 on: July 20, 2013, 06:05:06 AM »
Look closely at your code again, likely you missed a line/statement when typing in the code!  ;)

In fact, none of the elements of the values[] array should be initialized to zero, they all should have completely random values, as you nowhere actually initialize the array elements with a statement like
Code: [Select]
values[index]=0;
No variable shall be assumed to have a defined value unless you explicitly assign one to it. Declaring a variable (array or otherwise) will never initialize that variable to a specific default value.

Ralf

Offline jj2007

  • Member
  • *
  • Posts: 536
Re: Array initialization error
« Reply #2 on: July 20, 2013, 07:25:05 AM »
This is for local arrays. In contrast, global arrays are initialised to zero:

int values[10];   // make the array global, and it will be initialised to zero

int main (void)
{
//         int values[10];
        int index;

Roda

  • Guest
Re: Array initialization error
« Reply #3 on: July 20, 2013, 08:26:44 AM »
Thanks for the info it makes much sense. I guess I was assuming C automatically assigns zero to local array elements that were not initialized values. The book I'm reading says all the elements in the array should show an output of zero but not to assume anything is actually initialized with a value like what Bitbeisser was saying.

I followed jj2007 advice and made the array global and all elements of the array showed an output of zero.

Can anyone explain why would some local array elements show random numbers? What is it that is going on in the compiler or memory etc. that is making that happen? Like I said before it was only values[4] that showed an output of a random integer. Every other element showed an output of 0.

Thanks  :D

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2115
Re: Array initialization error
« Reply #4 on: July 20, 2013, 08:39:41 AM »
another way is to initialize array like this:
int values[10] = {0};
May the source be with you

Offline jj2007

  • Member
  • *
  • Posts: 536
Re: Array initialization error
« Reply #5 on: July 20, 2013, 12:11:41 PM »
Can anyone explain why would some local array elements show random numbers?

A global array is part of the global uninitialised data section (.data? in assembler notation). This area of memory gets zeroed by the OS before handing it over to the executable, so you don't need to zero it yourself.

In contrast, all local variables are set up on entry to a function using a stack frame:
main:
  push ebp
  mov ebp, esp
  sub esp, 3C  //create space for 0x3c bytes of local variables

When doing so, you get whatever garbage happened to be between the new and old stack pointer.

This seems, by the way, not true for double arrays:
int main (void)
{
   double myd[100];

This allocates the array in the .data section, at least in my tests with Pelles C.

C apparently does not foresee an option to initialise local variables, see
Visual studio 2005: is there a compiler option to initialize all stack-based variables to zero?
Is there a gcc flag to initialise local variable storage? ("certain copies of GCC ... have a -finit-local-zero option")

In Basic, Fortran, Python and many other languages, initialisation is standard. Even in Assembler you can easily write a macro (which uses a library function, one 5 bytes call for all local variables):
                MyTest proc arg1:DWORD, arg2:RECT
                LOCAL v1, v2, rc:RECT, buffer[100]:BYTE
                    ClearLocalVariables


The performance loss of initialisation is negligible, unless you call a function a Million times in an innermost loop (and even initialising 100 bytes of local variables a Million times costs a mere 40 ms, measured on a trusty old Celeron...).

I've tried to implement something similar in Pelles C, but it turns out to be very tricky because the compiler "optimises" the stack frame in various ways. Curious to hear if others have tried this road, too. Perhaps it could be squeezed into the PROLOGUE macro??
« Last Edit: July 20, 2013, 09:57:29 PM by jj2007 »

Offline Bitbeisser

  • Global Moderator
  • Member
  • *****
  • Posts: 772
Re: Array initialization error
« Reply #6 on: July 20, 2013, 11:17:04 PM »
Thanks for the info it makes much sense. I guess I was assuming C automatically assigns zero to local array elements that were not initialized values. The book I'm reading says all the elements in the array should show an output of zero but not to assume anything is actually initialized with a value like what Bitbeisser was saying.

I followed jj2007 advice and made the array global and all elements of the array showed an output of zero.

Can anyone explain why would some local array elements show random numbers? What is it that is going on in the compiler or memory etc. that is making that happen? Like I said before it was only values[4] that showed an output of a random integer. Every other element showed an output of 0.
It will show whatever random value is stored in the memory location that those variables are associated with.

Yes, the C standard defines that global variables should be initialized by the compiler with a 0/NULL value. Some other programming languages might be doing this for all variables by default (not sure about Python), but there are a lot of people that will consider not explicitly initializing variables, local or global, just bad programming practice. It is just one more thing that can lead to strange/unexpected/unwanted behavior in a program.

Ralf

Offline jj2007

  • Member
  • *
  • Posts: 536
Re: Array initialization error
« Reply #7 on: July 21, 2013, 01:12:45 AM »
Yes, the C standard defines that global variables should be initialized by the compiler with a 0/NULL value.  ... there are a lot of people that will consider not explicitly initializing variables, local or global, just bad programming practice.

Why should global variables be initialised to zero if the compiler (or rather: the OS) has done it already?

Offline Bitbeisser

  • Global Moderator
  • Member
  • *****
  • Posts: 772
Re: Array initialization error
« Reply #8 on: July 21, 2013, 06:45:18 AM »
Yes, the C standard defines that global variables should be initialized by the compiler with a 0/NULL value.  ... there are a lot of people that will consider not explicitly initializing variables, local or global, just bad programming practice.

Why should global variables be initialised to zero if the compiler (or rather: the OS) has done it already?
How do you know for sure that this has been done already? How do can you be certain that in a larger project a variable is global or local?
Sorry, IMHO, there is no point in arguing here, bad programming practice is bad programming practice. As a programmer, you should never rely on a compiler or an OS to do the work for you. And specially for a newbie, as the OP states he is, the earlier he gets used to work responsibly, the better...

Ralf

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2113
Re: Array initialization error
« Reply #9 on: July 21, 2013, 12:36:19 PM »
The OS when loading an executable doesn't know and doesn't care in what language it was write (an executable is an executable...).
It is a 'C' language requirement to init them to zero. The initialization is made in the CRT startup (CRT=C run time).
The uninitialized global variables reside in .bss section that in almost all file formats (PE, ELF, etc.) include only the section header not the section contents to spare file space on disk (and to fasten loading). The loader in this case allocates memory with the required size. The contents of that section can be whatever depending from the OS (zeroed or not).
That's why some global variables which 'zero' value is not a string of zero bits (look in C-STD spec for initial value of uninitialized global variables), are located in .data section instead of .bss, like the case of some structures holding not arithmetic types (or floats even if float representation of 0.0 is commonly a string of zero, but in different float representation can have different formats).
You may want look also here
« Last Edit: July 21, 2013, 12:46:27 PM by frankie »
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

Offline jj2007

  • Member
  • *
  • Posts: 536
Re: Array initialization error
« Reply #10 on: July 21, 2013, 12:52:36 PM »
It is a 'C' language requirement to init them to zero.
So will the compiler ignore a global int myvar=0;, or does it insert unnecessary extra code?

Quote
float representation of 0.0 is commonly a string of zero, but in different float representation can have different formats).
Is there any type of float in the C specs that represents a value different from zero for 0x00000000?

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2113
Re: Array initialization error
« Reply #11 on: July 21, 2013, 01:07:08 PM »
Hi JJ
It is a 'C' language requirement to init them to zero.
So will the compiler ignore a global int myvar=0;, or does it insert unnecessary extra code?
The exact behaviour is compiler (optimizer) dependent. If incidentally you want initialize your variable as zero you can omit initialization. Anyway as my personal programming habit I always init variables to avoid problems with compiler/OS changes, upgrades, bugs, etc.  8)

Quote
float representation of 0.0 is commonly a string of zero, but in different float representation can have different formats).
Is there any type of float in the C specs that represents a value different from zero for 0x00000000?
C language is so universal to include everything, EBCDIC for chars or whatever for other variables, while IEEE-754 is almost universal for float representation still may exist machines with different formats.

Anyway if you want more information you can take a look to the standard sheets. I gave a fast reading, but it is so large...  ::) and honestly I haven't time to deep consult it.
You can also compare C-faq here.

P.S. I also found this, maybe give more info.
« Last Edit: July 21, 2013, 02:32:03 PM by frankie »
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide