Consider the below C code. I would have thought that the variable bar was being instantiated every time and would thus point to different addresses in memory, but it doesn't.
for (i = 2; i < 7; i++) {
    struct foo bar;
    printf("struct %u\n", bar);
}
Output:
struct 13205520
struct 13205520
struct 13205520
struct 13205520
struct 13205520
In case it is not obvious, what I want is to generate 5 different structs—well, actually 5 different pointers to structs—at 5 different locations. How can I do this?
A pointer variable is a variable (a name that references some area of memory), but what's in that area of memory? What's the pointer itself? Well, it's a memory address, a way of referencing another memory location.
You cant have variables stored in the same memory address. You can point to a memory address and store the value in that memory address to a different memory address. No YOU are wrong, that is not 2 variables at the same address, that is a variable and a reference to the same variable. A reference is not a variable.
Yes, two or more references, say from parameters and/or local variables and/or instance variables and/or static variables can all reference the same object.
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.
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
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:
printf to print its address, the conversion specifier %u expects an unsigned int, not a structure.bar is uninitialized, passing it has undefined behavior.for body for the next iteration.%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]);
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With