1

The following code is trying to set the test array in the first for loop, but it can't be used in the second for loop.

int main()
{
    int *test[3];
        
    /** Try to set the array value one by one */
        
    for (int i = 0; i < 3; i++)
    {
        test[i] = &i;
    }
        
    /** Try to print the array value one by one */
    
    for (int i = 0; i < 3; i++)
    {
        int value = *test[i];
        printf("%d = %d\n", i, value);
    }
        
    return 0;
}

Here is the output:

0 = 3
1 = 3
2 = 3

What's wrong in my code and how to fix?

7
  • 4
    test[i] = &i - you assign pointers to a variable that does not exist when you print the array. This is undefined behavior. Don't use pointers in this code. Commented Oct 31 at 9:37
  • I want to store the int value in a (void *) pointer and use this pointer outside of the for loop somewhere, this main is used (int *) pointer for testing. Commented Oct 31 at 9:39
  • 1
    You don't store int values, you store pointers. Don't use pointers there. Commented Oct 31 at 9:40
  • 1
    There are no values, there are pointers in the array. Don't use pointers. Commented Oct 31 at 9:50
  • I have also tried int *nn = malloc(sizeof(int)); nn = i; test[i] = nn; but still not work. I don't know what's wrong. Commented Oct 31 at 9:56

2 Answers 2

5

If you want to store some int values, you don't need pointers at all:

#include <stdio.h>

int main() {
    int test[3];

    /** Try to set the array value one by one */
    for (int i = 0; i < 3; i++) {
        test[i] = i;
    }

    /** Try to print the array value one by one */
    for (int i = 0; i < 3; i++) {
        int value = test[i];
        printf("%d = %d\n", i, value);
    }
}

Output:

0 = 0
1 = 1
2 = 2

Live demo 1


If for some reason (which is not clear from your question) you need to store pointers, the pointers cannot point to i which is a local value in the for loop because they become dangling right after it, and so dereferrencing any of them invokes undefined-behavior.

You can solve it by allocating new int objects (e.g. using malloc), but in this case you must remember to release them (with free) eventually to avoid a memory leak:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int * test[3];

    /** Try to set the array value one by one */
    for (int i = 0; i < 3; i++) {
        test[i] = malloc(sizeof(int));
        *test[i] = i;
    }

    /** Try to print the array value one by one */
    for (int i = 0; i < 3; i++) {
        int value = *test[i];
        printf("%d = %d\n", i, value);
    }

    /** free memory: */
    for (int i = 0; i < 3; i++) {
        free(test[i]);
    }
}

Live demo 2

Note that I omitted error checking (e.g. malloc returns null upon failure) which should be added to the final code.

Alternatively you can set the pointers to point to some elements outside the for loop - e.g. ones in a static array.

Sign up to request clarification or add additional context in comments.

2 Comments

I have tried int *nn = malloc(sizeof(int)); nn = i; test[i] = nn; in the first for loop but still not work. I need to use the array pointer in other function.
I updated the answer with the proper allocation and deallocation.
3

Wanted to add a bit more insight into the initial implementation (question).
-----------------------------------------------
In the first loop, you create a variable i.
This variable i has a specific memory address — let’s say it’s 0xabab.

During the first loop, i takes on the values 1 through 3, but its memory address doesn’t change.
Because of that, every element of test[i] ends up storing the same address (the address of i, 0xabab).

In the second loop, i is declared again in a different scope, so it gets a new memory address — it’s no longer 0xabab.

When you later print the values stored in test[i], you’re actually printing whatever is stored at the old address (0xabab), which still holds the value 3 (the last value from the first loop).

That’s why all elements print 3.

2 Comments

In the second loop, i is declared again in a different scope, so it gets a new memory address — it’s no longer 0xabab. This is not true generally. This is implementation detail, and the second i can re-use the storage of the first i.
Welcome to stackoverflow. I recommend to make a small edit and give a hint that this is undefined behaviour (which of course was not intended)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.