Reputation: 1442
struct abc filled[]={{"aa",10},{"bb",20}};
printf("[%u,%u]\n",filled,&filled);
printf("[%u,%u]\n",filled[0],&filled[0]);
printf("[%u,%u]\n",filled+1,&filled+1);
printf("[%u,%u]\n",filled[1],&filled[1]);
how the filled array is arranged in memory? filled being the name of array returns the base address of the array...similarly &filled. but filled[0] gives some unknown value, may be the address and the googly part is &filled[0] which gives the value 10. I am not able to get the logic. following is the output i am getting
[2293552,2293552]
[4206592,10]
[2293560,2293568]
[4206595,20]
Upvotes: 0
Views: 264
Reputation: 24249
Your code
struct abc filled[]={{"aa",10},{"bb",20}};
printf("[%u,%u]\n",filled,&filled);
printf("[%u,%u]\n",filled[0],&filled[0]);
Before we can discuss this any further, we need to have some idea of what "struct" looks like. You didn't provide a definition so I'm going to assume it is something like
struct abc {
const char* str;
int i;
};
So filled
is an array of these objects:
filled[] = {
struct abc { str = "aa", i = 10 },
struct abc { str = "bb", i = 20 }
};
filled[0]
refers to the first struct abc in the space.
{ str = "aa", i = 10 }
In memory, in a 32-bit build, these will be laid out, with [...] representing a byte:
[ptr][ptr][ptr][ptr][i][i][i][i]
On a 64-bit system, these will be laid out as
[ptr][ptr][ptr][ptr][ptr][ptr][ptr][ptr][i][i][i][i]
The exact order of the bytes that make up str
and i
will depend on the architecture.
Now, your code...
struct abc filled[]={{"aa",10},{"bb",20}};
printf("[%u,%u]\n",filled,&filled);
printf("[%u,%u]\n",filled[0],&filled[0]);
printf has a limitation. The underlying function cannot actually see your arguments - it just gets data on a stack and it uses the print format as a guide.
Ultimately what's going horribly wrong is that you are passing a struct as a printf argument.
printf("[%u,%u]", filled[0], &filled[0]);
filled[0]
resolves to a struct abc
.
What's happening is that the program is putting the value of filled[0] onto the stack for printf to use. The first %u in the format mask consumes the str
component and the second consumes the i
.
If this is your complete program:
#include <stdio.h>
struct abc {
const char* str;
int i;
};
int main() {
struct abc filled[] = { { "aa", 16 }, { "bb", 20 } };
printf("filled = %p\n", filled);
printf("&filled = %p\n", &filled);
printf("filled[0] = %p\n", filled[0]);
printf("&filled[0] = %p\n", &filled[0]);
printf("filled[0].str = %p\n", filled[0].str);
printf("filled[0].i = %d\n", filled[0].i);
return 0;
}
Here is the output:
filled = 0xbfba5cb0
&filled = 0xbfba5cb0
filled[0] = 0x80485b0 <--+
&filled[0] = 0xbfba5cb0 | filled[0] actually printed the .str value
filled[0].str = 0x80485b0 <--+
filled[0].i = 16
What you are missing is the following compiler warning, because you're compiling with Visual Studio or without -Wall:
prog.c: In function ‘main’:
prog.c:12:5: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘struct abc’ [-Wformat=]
printf("filled[0] = %p\n", filled[0]);
When you do
printf("[%u, %u]\n", filled[0], &filled[0]);
The program does the following:
push stack (const char*) "[%u, %u]\n" // in 32-bit, 4-bytes of pointer.
push stack (struct abc) filled[0] // pushes the entire of filled[0], str and i, 8 bytes.
push stack (struct abc*) &filled[0] // pushes another 4 bytes.
And the resulting stack looks like this
printf never uses the value of "&filled[0]" because you didn't specify the right formats to read the data on the stack. If you instead used
printf("filled[0].str=%p, filled[0].i=%u, &filled[0]=%p\n", filled[0], &filled[0]);
then you would get more meaningful data, but this is a dangerous way to achieve the result because it makes a lot of assumptions about data layout and the stack.
Fundamentally, your problem is that you are doing this:
printf("%u", filled[0]);
where filled[0] is not a simple datatype.
Upvotes: 2
Reputation: 320361
Format specifier %u
in printf
requires an argument of type unsigned int
. You are supplying it with arguments of completely unrelated types: pointers and objects of struct type. Because of this your code exhibits undefined behavior. The code is broken and its output is completely meaningless. There's not much point in trying to analyze or explain it. (The explanation certainly exists, but it has nothing to do with the primary question.)
As for how arrays are arranged in memory... StackOverflow is choke-full of repetitive answers to this very question. Just do a search.
Upvotes: 3