-2

I wanted to know why printing the address of a variable in c gives the output as something like 823759733 while, doing the same in c++ shows 0x7ff6474009c?? Is this the work of 'cout', that formats the address as a hex? or is the variable memory address cloaked to show some arbitrary address to encapsulate it?? I know that everything is going on inside virtual memory in C++, is this the same for C?

example -

int a=10;
int* ptr=&a;
printf("%d", ptr);

it should print an integer.

the same code written in c++ and

cout<<ptr

it shows a hex(I want to know why?)

  • 2
    How do you print the address in C? It looks like you're doing something wrong in your C code. Did you enable compiler warnings? Your compiler should show you what you're doing wrong. – Thomas Sablik Jun 26 '20 at 08:39
  • 2
    When asking people to analyze your code, please show your code – tenfour Jun 26 '20 at 08:39
  • references (addresses) are rather pointless in the decimal form. It is hard to find the use of a decimal address – 0___________ Jun 26 '20 at 08:58
  • 1
    In C, `printf("%d", ptr);` is _undefined behavior_ as the print specifier does not match the argument. Use `printf("%p", (void*) ptr);` – chux - Reinstate Monica Jun 26 '20 at 09:20

3 Answers3

4

I guess you are printing in C something like this:

void* p;
...
printf("%d", p);

The %d specifier prints as an integer, output as base-10.

And I guess in C++ you're doing something like:

void* p;
...
std::cout << p;

Here, because of C++ strong typing, cout knows p is a pointer, and not an integer. Pointers are output in base 16 by default.

tenfour
  • 36,141
  • 15
  • 83
  • 142
1

That's the problem

printf("%d", ptr);

The result can be completely wrong. On my system a int has 4 bytes and a pointer has 8 bytes. When I try to print a pointer as decimal (%d) it causes undefined behavior. In my example I see the undefined behavior as overflow. You should use %p to print pointers

printf("%p", ptr);

Your compiler should show you a warning like

warning: format '%d' expects argument of type 'int', but argument 2 has type 'int *' [-Wformat=]

An example of

#include <stdio.h>

int main() {
    int a;
    int* ptr = &a;
    printf("%d", ptr);
}

Compile output:

prog.c: In function 'main':
prog.c:5:14: warning: format '%d' expects argument of type 'int', but argument 2 has type 'int *' [-Wformat=]
    5 |     printf("%d", ptr);
      |             ~^   ~~~
      |              |   |
      |              int int *
      |             %ls

Runtime output:

-204940372
Thomas Sablik
  • 16,127
  • 7
  • 34
  • 62
  • Thanks for the answer, totally understood the format specifiers, but when you said, your system has 4 bytes for an int, and 8 bytes for a pointer, that might cause some overflow issues. If I however set the pointer type as an int pointer, the pointer should now hold 4 bytes instead of 8, right? And it should not cause any issue? Sorry for going a bit in-depth, I am always curious of learning – Nishad Sandilya Jun 26 '20 at 09:00
  • @NishadSandilya No, all pointers have the same size. A pointer has 4 bytes on a 32 bit system and 8 bytes on a 64 bit system. A int pointer has the same size as and double pointer or a void pointer. – Thomas Sablik Jun 26 '20 at 09:02
  • "all pointers have the same size" --> not quite. Yet the point here is the the size of `int` and sizeof `int *` can differ. "pointer has 4 bytes on a 32 bit system and 8 bytes on a 64 bit system" --> not quite either. Although common true as you say, the N-bit of a system more commonly refers to the native integer size, not pointer size. Pointer size and native integer size can differ. Native integer may differ from `int`. – chux - Reinstate Monica Jun 26 '20 at 09:07
  • @chux-ReinstateMonica I learned that the N-bit describes the memory addresses. A 32-bit system has addresses with 32 bit and therefore can use up to 4 GB of memory. A 64-bit system uses 64 bit addresses and can use more memory. – Thomas Sablik Jun 26 '20 at 09:10
  • And if the processor was 8-bit - what would the memory address then be? I'd suggest "N-bit describes the memory addresses" is not that correct. [/Word_(computer_architecture)](https://en.wikipedia.org/wiki/Word_(computer_architecture)) may be useful. – chux - Reinstate Monica Jun 26 '20 at 09:13
  • @chux-ReinstateMonica You're mixing things up. You can run a 16-bit system (with 16-bit addresses) on a 8-bit processor. A 16-bit system has up to 64kb memory. – Thomas Sablik Jun 26 '20 at 09:17
  • Well looks like we are not finding common ground. IMO, an N-bit system refers to the native integer width, you see N as the pointer width. Both can be right when they are the same. I see the data memory pointer size, program space pointer size and native integer size as 3 independent parameters. A "n-bit" system is insufficient to express those 3. IAC, C supports these 3 as potentially different - whatever we call them. – chux - Reinstate Monica Jun 26 '20 at 09:38
  • 1
    Note that using the wrong format specifier is technically UB even if the size of the argument matches. – eerorika Jun 26 '20 at 09:42
  • @chux-ReinstateMonica The system I'm working on is commonly called 64-bit architecture. The `int` has a size of 4 byte and the pointers have a size of 8 bytes. Obviously the 64-bit describe the pointer size and not the `int` size. But currently I'm not sure if you mean something different with _"native integer size"_. – Thomas Sablik Jun 26 '20 at 09:56
  • Native integer size refers to the processors widest integer which the handles most operations. When this is less than 16, `int` still must be 16 per C req's. When it is 16 or 32, then `int` typicality matches. When native integer size is 64+, `int` typically remains 32 for code compatibility reasons. – chux - Reinstate Monica Jun 26 '20 at 10:30
  • @chux-ReinstateMonica You wrote _"'all pointers have the same size' --> not quite."_ Did you mean there are pointers in C or C++ that have a different size than other pointers or did you mean there are CPU pointers that have different size than other pointers? – Thomas Sablik Jun 26 '20 at 10:45
  • @ThomasSablik: In C, the only requirements are that `void *` and `char *` have the same size and alignment, that pointers to qualified types have the same size as their unqualified equivalents, that all `struct` pointer types have the same size, and that all `union` pointer types have the same size. On x86-like systems all pointer types tend to be the same size, but that doesn’t have to be the case. And the size of the pointer type does not depend on the size of the pointed-to type. – John Bode Jun 26 '20 at 13:02
  • @ThomasSablik A common pointer size difference is pointers to objects and pointers to functions. That is why `void *p = sqrt:` may not work. C acknowledges that as a `void *` has well defined behavior between _objects_ pointers and `void *`, not necessarily with function pointers. Less common is that objects pointers of one type may differ from others. See C17 § 6.2.5 26 This is not common today. – chux - Reinstate Monica Jun 26 '20 at 13:30
0

The role of format specifiers for printf in C is taken by different overloads for operator<< in C++. In the C code you didn't show you explicitly asked to print the decimal representation, when you call std::cout::operator<< the appropriate overload is chosen. Printing memory adresses as hex is the common convention. If you like you can print them as decimals in C and in C++.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185