Why does the variable in this loop point at the same memory location?

The scope of bar only exists within one iteration of the loop. That means that when the next struct foo is created, it will be put in the same place as the old bar, because as far as the compiler sees it, the bar is no longer necessary. Looking at your example, it doesn't seem like you need to handle all of the bar's at once. So you might be okay with them all being at the same location. However, if you need to deal with multiple at a time, I can think of two possible solutions.

Putting the scope outside of the loop

To do this, you'll need an array of struct foo's. The scope of the array needs to be outside of the loop. For example:

struct foo bar_list[5];
for (i = 2; i < 7; i++) {
    printf("struct %p\n", (void *)&bar_list[i - 2]);
    // use the foo's here

Then each iteration of your for loop can modify one of the values

Allocating on the heap

If you're okay with storing five pointers in memory, you can allocate each bar somewhere on the heap. You would probably end up just using an array anyway, so this would probably only be useful if you needed to return the structs into another function. You'd need to do something like this:

struct foo* bar_list[5];
for (i = 2; i < 7; i++) {
    bar_list[i - 2] = malloc(sizeof(struct foo));
    printf("struct %p\n", (void *)bar_list[i - 2]);
    // do anything else you need to do

It's also worth mentioning, as someone else pointed out, that %p would be used to print a pointer address.

Your code has undefined behavior:

  • you cannot pass a structure to printf to print its address, the conversion specifier %u expects an unsigned int, not a structure.
  • furthermore, bar is uninitialized, passing it has undefined behavior.
  • each iteration instantiates a new structure that is uninitialized, possibly at the same location and it goes out of scope as soon as you leave the for body for the next iteration.
  • to print the location of the structure, use %p and pass (void *)&bar, but it is unspecified whether the address of bar will be the same for each iteration or not.

Most compilers will reuse the same space for bar at each iteration, but a compiler could conceivably generate code to randomise the address of bar in a proprietary way in order to make the code more resilient to exploits.

If you want all structures to reside in different addresses, you can define an array of structures outside the scope of the loop and print their addresses this way:

struct foo bar[5];
for (int i = 2; i < 7; i++) {
    printf("address of struct bar[%d] is %p\n", i - 2, (void *)&bar[i - 2]);