3

Can anyone please explain the output for the following program? I get an infinite loop if used a[i] = 0; and a segfault when I used a[i] = i; and also the i ranges between 0 - 9 when used a[i] = 0; whereas it goes to 39 when used a[i] = i; before giving a segfault.

#include<stdio.h>
#include<stdlib.h>
int mult(int a, int b);
int main()
{
    int a[10];
    int i = 0;
    for(i=0; i < sizeof(a); i++)
    {
        a[i] = i;
        printf("a[i]=%d i=%d\n", a[i], i);
    }
    return 0;
}
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
Hardhik
  • 151
  • 7
  • 5
    What you think `sizeof(a)` does ? – P0W Sep 16 '13 at 17:43
  • Where is `mult` defined? – Keith Thompson Sep 16 '13 at 17:44
  • @KeithThompson `mult` is never used so it's not relevant to the problem. – Colin Basnett Sep 16 '13 at 17:44
  • Can you provide us a description of what this program is supposed to do? – Colin D Sep 16 '13 at 17:45
  • *"I get an infinite loop if used a[i]=0"* Good old buffer overflow. `&a[10] == &i` – Havenard Sep 16 '13 at 17:49
  • Read [Weird behavior when printing array in C?](http://stackoverflow.com/questions/18009725/weird-behavior-when-printing-array-in-c/18009736#18009736) – Grijesh Chauhan Sep 16 '13 at 17:50
  • @Havenard can you please elaborate on the reason for getting infinite loop. – Hardhik Dec 14 '13 at 08:52
  • @hardhik You may think `sizeof(a)` is 10, but it is at least 40. `sizeof()` gives you the size of the structure in bytes, and each `int` element in `a` has 4 or 8 bytes depending on the architecture, so you are trying to loop from 0 to 39 instead of 0 to 9. You will loop from `a[0]` to `a[9]` and then overflow to `a[10]` that don't exist. If `a[10]` existed, it would be in the same space in memory where `i` is right now. Thats why when you change the value of `a[10]` you are actually overwriting the value of `i`. Changing `a[10]` to 0 will set `i` to 0 aswell, and you will loop all over again. – Havenard Dec 14 '13 at 16:11

4 Answers4

7

When you apply the sizeof operator to an array type, the result is the total number of bytes in the array, i.e, sizeof(a) determines the number of bytes in a which is not the number of elements in the array in this case. Use sizeof(a)/sizeof(a[0]) to get number of elements in the array a.
Replace

for(i=0;i<sizeof(a);i++)

with

for(i=0;i<sizeof(a)/sizeof(a[0]);i++)

Also, no need to initialize i twice.

haccks
  • 104,019
  • 25
  • 176
  • 264
  • 3
    `sizeof(a)/sizeof(a[0])` also determines the size of the entire array. It's just the units that differ. –  Sep 16 '13 at 17:49
  • @H2CO3; More precisely `sizeof(a)/sizeof(a[0])` gives the length of array. – haccks Sep 16 '13 at 17:51
  • @hacks so does `sizeof(a)`. In different units. –  Sep 16 '13 at 17:52
  • @H2CO3; Uff! I agreed :) – haccks Sep 16 '13 at 17:55
  • 2
    to clarify you can quote : `When you apply the sizeof operator to an array type, the result is the total number of bytes in the array` from [`sizeof` Operator](http://c0x.coding-guidelines.com/6.5.3.4.html) – Grijesh Chauhan Sep 16 '13 at 17:56
  • 2
    @GrijeshChauhan Thanks! :) Maybe add "which is not the number of elements in the array unless it's an array of characters". –  Sep 16 '13 at 17:56
  • 1
    @H2CO3; On your request I added this line to my question :) – haccks Sep 16 '13 at 18:02
  • I too think that adding sizeof() might lead the iterator(i) out of range but the results are unexpected hence the question !. – Hardhik Sep 30 '13 at 16:41
5

You probably want to change this line:

for(i=0;i<sizeof(a);i++)

to this:

for(i=0;i<sizeof(a)/sizeof(a[0]);i++)

Note:

  • sizeof(a) gives the number of bytes in a[].

  • sizeof(a)/sizeof(a[0]) gives the number of elements in a[].

Paul R
  • 208,748
  • 37
  • 389
  • 560
3

sizeof doesn't do what you think it does. It's returning the number of bytes occupied by the entire array.

You want the numeric length of the array, not the byte size.

Try something like this:

const int array_size = 10;
int a[array_size];

for (int i = 0; i < array_size; i++) {
    a[i] = i;
    printf("a[%d] = %d\n", i, a[i])
}
Tyler Jandreau
  • 4,245
  • 1
  • 22
  • 47
2

If you want to know how far to loop, without storing it in a separate const, use sizeof(a)/sizeof(a[0])

Tawnos
  • 1,877
  • 1
  • 17
  • 26