An array is preserving data between function calls in C

3612 views c
2

Why is the data preserved for the second call when I haven't used static?

Here is the code, the output and what I've expected the output should be.

#include <stdio.h>

void fun(int len)
{
  int arr[10];
  int i;

  for (i = 0; i < len; i++)
    arr[i] = (i+1) * 10;

  for (i = 0; i < 10; i++)
    printf("%d ", arr[i]);

  printf("\n");
}

int main(void) {
  fun(10);
  fun(4);

  return 0;
}

output:

10 20 30 40 50 60 70 80 90 100 
10 20 30 40 50 60 70 80 90 100

expected output:

10 20 30 40 50 60 70 80 90 100 
10 20 30 40 0 0 0 0 0 0 

answered question

Undefined behaviour from trying to use the indeterminate values of an uninitialized array.

This is just pure luck. The array is stored on the stack at a given stack frame address in the first call. When fun returns, the stack pointer is popped back to its original address. When you call fun a second time, just by luck, the second call gets the same address for the stack frame. This behavior can not be relied upon [to do anything useful]. Beyond this simple example, such reliance can cause unpredictable/undefined behavior, including a segfault. For example, if you did fun(10); fun2(); fun(4);, fun2 might corrupt the data by writing to its frame in different way.

Thanks for your answers. C is really interesting language.

3 Answers

2

Please initialize array.

Like this

void fun(int len)
{
  int arr[10] = {0};  //changed
  int i;

  for (i = 0; i < len; i++)
    arr[i] = (i+1) * 10;

  for (i = 0; i < 10; i++)
    printf("%d ", arr[i]);

  printf("\n");
}

posted this
8

int arr[10]; declares an array of 10 int elements on the stack. Its elements are uninitialized. If you attempt to access them without initialization, as is the case with fun(4), you may see garbage values, you may happen to see old memory contents (as you did here), or you may crash the program with a segmentation fault if the memory page belongs to another program. You may even get your expected output! In fact, anything can happen because behavior is undefined by the specification.

To meet your expectations, initialize the array in any way you choose, such as one of the following:

int arr[10] = {};
int arr[10] = {0};
int arr[10];
memset(arr, 0, sizeof(int) * 10);
int arr[10];

for (int i = 0; i < 10; i++) {
    arr[i] = 0;
}

etc.

posted this
7

You are invoking undefined behavior by accessing uninitialized memory. The result could be literally anything, including your computer growing legs and running away.

In practice, what is probably happening is that your function calls occupy the same place on the stack since there are no other calls between or within them. The arr variable ends up on the same spot on the stack both times. The first initialization is more comprehensive than the second, so you don't see total garbage. This is to be expected, but certainly never relied upon.

posted this

Have an answer?

JD

Please login first before posting an answer.