0

I have a struct

 struct abc{
     char c;
     char d;
    }

And I did

  void main(){
    struct abc obj;
    struct abc obj1;
    struct abc obj2;
   // char *h=obj;
    printf("%x %x %x\n",&obj,&obj1, &obj2);
  }

I got printed address like this

1460381e 1460381c 1460381a

First question

Why they are reversed order?

Second Question

every digit in the address is like 1 or 4 or 6 or etc. in the addresses above is 4 bit value. Since Hex is 4 bit to address a single Hex digit. And I am on x86-64 machine then does it mean the addresses which are using 32 bit address. so I am assuming that my x86-64 has 64 in name but basically a 232 = 4,294,967,296 bytes of memory contained. But I recently upgraded my system memory to 16GB so does this mean whatever program I make is basically can only contain 4 GB of memory (assume again hypothetically speaking ). Where all the memory goes. How to increase this number so I can use more memory say I am using Linux and gcc to compile or any system configuration or is it a Linux default?

Question 3

also in above code how much memory does it take to execute and have printf displayed. I am assuming execution of printf takes care of displaying it on screen. or is there any other address involved containing the displaying thing.

And is it any how possible I can view the address of printf I know I can use dissembler like rasm but does all the addresses in the question I mentioned are virtual address or physical address

Thank for any info

user786
  • 3,902
  • 4
  • 40
  • 72
  • If your boss tells you to go get things from a truck and put them on a shelf, and those are the only instructions, will the items necessarily end up on the shelf in the same order they were in the truck? When you tell the compiler you want some things in a function, you have no reason to expect them to end up in the same order in memory as they are in your source code. You might get items from the truck right to left and put them on the shelf left to right. Or right to left. Or you might get one big item and some others you can carry and put those on the shelf and then go back for more. – Eric Postpischil Mar 31 '21 at 14:16

2 Answers2

2

Why they are reversed order?

There's no requirement that objects be allocated in a specific order; that's up to the specific implementation. On x86/x86-64, the stack grows "downwards" towards decreasing addresses, so each time you push something on the stack it will have a lower address. A straightforward translation of the code will allocate obj before obj1 before obj2, so obj will be at the highest address and obj2 at the lowest.

That doesn't have to be the case, however.

And I am on x86-64 machine then does it mean the addresses which are using 32 bit address.

You're using the wrong format specifier to print out your pointer values, which is effectively giving you garbage output. %x expects its corresponding argument to have type unsigned int and it is treating those pointer values as unsigned ints. Use %p to print pointer values:

printf( "%p\n", (void *) &obj ); 

This is probably the only time you need to explicitly cast a pointer to void * in C.

also in above code how much memory does it take to execute and have printf displayed.

That is a function of the specific implementation, and AFAIK there's no good way to obtain that information using C. You can examine the disassembled code to get an idea.

John Bode
  • 119,563
  • 19
  • 122
  • 198
1

The code is invalid. %x printf format specifier expects a unsigned int variable, yet you pass struct abc* pointer. The behavior of code is undefined. To print pointer value use printf("%p\n", (void*)&obj) (or printf("%jx", (uintmax_t)(uintptr_t)&obj)). The code "works" because of how values are passed on stack to printf on your platform.

And, also, you are using %x specifier and unsigned int has 32-bits on your platform, so it will print 32-bits from registers anyway. As such, your program is just an invalid way of checking how big pointers are, which led you to wrong conclusions.

Why they are reversed order?

From wikipedia x86:

[...] The stack grows toward numerically lower addresses [...]

And I am on x86-64 machine then does it mean the addresses which are using 32 bit address

No. Your program prints 32-bits because %x prints 32-bits on your platform.

And anyway, 0x0000000000000001 is a 64-bit number, as much as 1 is. The number of leading zeros does not make a number take less space. The type, not value, determines the count of bytes used. A pointer has 64-bits, no matter how many leading zeros it has. %x format specifier does not print leading zeros.

How to increase this number so I can use more memory say I am using Linux and gcc to compile or any system configuration or is it a Linux default?

(With default configuration) you do not have to take any action.

how much memory does it take to execute and have printf displayed

Inspect the generated assembly code, see http://godbolt.com . Note that compiler can optimize code - it's completely valid for your compiler to optimize the code compleatly and just do int main() { puts("1460381e 1460381c 1460381a"); }. Research optimization and as-if rule in C.

how possible I can view the address of printf

Technically casting a function pointer to anything else then a function pointer is undefined behavior. Still the following code will work on gcc:

 printf("%p\n", (void*)printf);

does all the addresses in the question I mentioned are virtual address or physical address

Virtual. At least see ASLR.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • `Technically casting a function pointer to anything else then a function pointer is undefined behavior. Still the following code will work on gcc:` ok I can get the address where the code reside like this. and how to print `printf` function call address? – user786 Mar 31 '21 at 13:38
  • `how to print printf function call address?` What is a "call address"? I guess you are referring to [program counter](https://en.wikipedia.org/wiki/Program_counter). – KamilCuk Mar 31 '21 at 13:39
  • I like the address where `printf` is written in the text segment – user786 Mar 31 '21 at 13:41
  • `printf("%p\n", (void*)printf);` prints the address where `printf` is written in text segment. – KamilCuk Mar 31 '21 at 13:41
  • I mean if I want address of `printf` call statement inside main function – user786 Mar 31 '21 at 13:43
  • 1
    @666 - there's no (good, standard, portable) way to obtain the address of a specific instruction in C. – John Bode Mar 31 '21 at 13:51
  • 1
    @666: Debug your program with GDB and use `disas` or `layout asm` to see disassembly instead of C source. Or just use `objdump -drwC -Mintel` on the executable or the `.o` from `gcc -c -O2`. (Normally I'd suggest looking at the compiler's asm output, [How to remove "noise" from GCC/clang assembly output?](https://stackoverflow.com/q/38552116), but it seems you want to see addresses and instruction sizes, not just number of instructions.) – Peter Cordes Mar 31 '21 at 18:13