For example:
sizeof(char*)
returns 4. As does int*
, long long*
, everything that I've tried. Are there any exceptions to this?

- 1,035
- 2
- 18
- 35

- 15,166
- 16
- 39
- 31
-
72Why mark this down? Good question for any beginner. – Martin York Dec 29 '08 at 23:11
-
2I suspect that another question is hiding in this one: "What is sizeof?" or may be "Why is sizeof
== 4? What's so special about 4?". Am I right? – Dec 31 '08 at 17:14 -
2Well, it depends on your platform. Most implementations share a same size for every kind of pointer on a specific platform. – phoeagon May 16 '13 at 12:13
-
Please ask for either C or C++, not for both in the same question. This are 2 different languages. Only include both when you ask about the differences or similarities between them. – 12431234123412341234123 Sep 07 '20 at 11:17
17 Answers
The guarantee you get is that sizeof(char) == 1
. There are no other guarantees, including no guarantee that sizeof(int *) == sizeof(double *)
.
In practice, pointers will be size 2 on a 16-bit system (if you can find one), 4 on a 32-bit system, and 8 on a 64-bit system, but there's nothing to be gained in relying on a given size.

- 4,521
- 4
- 33
- 57

- 56,304
- 9
- 91
- 158
-
116And 3 bytes on a 24-bit system. Yes, I've worked on one. Welcome to the world of embedded devices. – dwj Dec 29 '08 at 23:13
-
37I've worked on 16-bit systems with 20-bit pointers as well. I should go see what sizeof returns in that case... – Judge Maygarden Dec 29 '08 at 23:16
-
6@monjardin: IIRC, the 8086 was like that. There was a 16 bit address and a 4 bit segment register. I believe a normal "NEAR" pointer was 16 bits and a pointer declared as "FAR" was more, probably 24, though I'm not sure. – rmeador Dec 29 '08 at 23:22
-
I worked on a (32-bit) system where the 'char *' to something had a different bit representation to the 'anthing_else *' to the same memory location. You learned to ensure that 'malloc()' was declared (because in those days of yore, malloc() returned 'char *' and not 'void *'). Beware! – Jonathan Leffler Dec 30 '08 at 00:10
-
(cont): The size of the pointers was the same in all cases; it was just the bit pattern that differed. I've not seen systems where pointers to different data types have different sizes. I have seen systems where code (function) pointers are different sizes from data pointers. – Jonathan Leffler Dec 30 '08 at 00:14
-
In certain memory models, a pointer on an 8086 was 32 bits. A 16-bit segment and a 16-bit offset. The processor would combine these by shifting the segment 4 bits to the left and adding the offset, resulting in a 20-bit address. Two different pointers could point to the same physical address! fun! – Ferruccio Dec 30 '08 at 03:27
-
16 bit systems are easy to find. Any code that runs in THUMB mode on an ARM chip. – ApplePieIsGood Dec 30 '08 at 15:26
-
Sorry, @ApplePieIsGood: ARM THUMB code is still 32-bit code. It's just a technique to compress the instruction size from 32-bits to 16-bits, but the address space is still the same. – Ben Combee Dec 30 '08 at 16:40
-
22another guarantee is that sizeof(char*) == sizeof(void*) , because they have to have the same representationss (object [size] and value [set of bits relevant for their value] representation) – Johannes Schaub - litb Jan 03 '09 at 16:03
-
1Ferruccio: It's not old. My Core 2 Quad processor also supports real mode ;-P – Mehrdad Afshari Jan 09 '09 at 13:59
-
Of course if you have a pointer to a member function of a class that uses multiple or virtual inheritance, then you'll likely get completely different pointer sizes. – Eclipse Jan 13 '09 at 22:55
-
itanium sometimes uses 2word (2 pointers) for representing 1 function pointer. – osgx Mar 24 '10 at 00:19
-
1There are other guarantees such as `sizeof(int) <= sizeof(long)`. They could be the same or `long` could be massively larger than `int`, but it'll never be smaller. – Jon Hanna Aug 10 '12 at 12:52
-
-
7Since the question asks for exceptions it should be noted that non-static member function pointers are often a different size to normal pointers and also vary by platform, type, etc. Other than that +1. – John5342 May 30 '13 at 12:59
-
18 and 16 bit is everywhere. Washing mashines, fridges, micros, remote controllers, car keys. – Kobor42 Jul 16 '13 at 20:34
-
1There's also a guarantee that all pointers to structs have the same size and layout, and all pointers to unions have the same size and representation. And pointers to signed/unsigned quantities. And pointers to plain/const/volatile objects. – gnasher729 Aug 30 '15 at 13:34
-
@gnasher729: I know there are guarantees about *casting* pointers, but where is there a guarantee about the size and representation? – Sep 23 '15 at 06:03
-
3@JohannesSchaub-litb: where does the standard says that `sizeof(char*) == sizeof(void*)` ? – Destructor Apr 04 '16 at 15:29
-
Does it mean that, no matter what the data type is, address is address and that's what the pointer stores, for that reason it must be the same size? – dud3 Apr 03 '17 at 21:00
-
-
@chux-ReinstateMonica: N1570 6.2.5 paragraph 28 specifies that in C, "A pointer to void shall have the same representation and alignment requirements as a pointer to a character type". I think that would imply that they are the same size. – supercat Mar 23 '20 at 22:07
-
@supercat Agree. In the last 3 yr, I have learned of that spec. I suspect the allowed variation of object pointer size amongst `int, FP, Struct, char` is a feature of the past - I know of no now variation. OTOH, function pointers and object pointer vary. – chux - Reinstate Monica Mar 23 '20 at 22:39
-
How can be that `sizeof int* != sizeof double*`? Does it mean that `int` or `double` located in the heap cannot have some bigger size addresses? For example if `sizeof int*` is 4 and `sizeof double*` is 8 then doubles can have large 8-byte addresses in the heap, while ints are capped only to have 4-byte addresses in the heap? And what's about user-defined types? Is it also be possible that `sizeof class1*` != `sizeof class2*`? – IC_ May 06 '21 at 09:27
-
It should be pointed out that `sizeof(char) == 1` is a definition. So, `sizeof(int) == 4` means that an `int` is four times as big as a `char` even if a `char` is, say, 16 bits. – Daniel Walker May 31 '22 at 17:15
Even on a plain x86 32 bit platform, you can get a variety of pointer sizes, try this out for an example:
struct A {};
struct B : virtual public A {};
struct C {};
struct D : public A, public C {};
int main()
{
cout << "A:" << sizeof(void (A::*)()) << endl;
cout << "B:" << sizeof(void (B::*)()) << endl;
cout << "D:" << sizeof(void (D::*)()) << endl;
}
Under Visual C++ 2008, I get 4, 12 and 8 for the sizes of the pointers-to-member-function.
Raymond Chen talked about this here.

- 44,851
- 20
- 112
- 171
-
4Pointers to member functions are a real pain. It is unfortunate that not all compilers does it like the Digital Mars C++ compiler, which return 4 in all cases. – dalle Feb 18 '09 at 15:21
-
-
2@Gob00st: The only thing that's defined is that char is 1. Other types can be whatever size is relevant to that compiler. There's no requirement for consistency between these pointer types. – Eclipse Nov 03 '12 at 22:38
-
-
5
-
@ColeJohnson where is the relation coming from? Should the first <= be <, namely `char` < `short`? – user3207158 Nov 11 '19 at 05:25
-
@user3207158 That relation comes from the standard. It does not say anything about their bit widths, but it does guarantee that all sizes are bigger or equal to the previous. `char` is always smaller than or equal to `short`, ..., `int` is always smaller than or equal to `long`, etc. I don’t have the standard on hand, so I can’t give a reference ATM. – Cole Tobin Nov 12 '19 at 16:53
Just another exception to the already posted list. On 32-bit platforms, pointers can take 6, not 4, bytes:
#include <stdio.h>
#include <stdlib.h>
int main() {
char far* ptr; // note that this is a far pointer
printf( "%d\n", sizeof( ptr));
return EXIT_SUCCESS;
}
If you compile this program with Open Watcom and run it, you'll get 6, because far pointers that it supports consist of 32-bit offset and 16-bit segment values

- 4,390
- 23
- 18
-
5Not segment, but selector rather - it isn't a part of the memory address, but an index entry in the LDT or GDT and has some access flags – Roee Shenberg May 29 '12 at 01:45
-
1Why are there segments and offsets in x86 while the address space is flat? – phuclv Mar 05 '14 at 09:20
-
@LưuVĩnhPhúc Because it saves space for the very common case of near pointers, which can be encoded shorter. – Christopher Creutzig Mar 08 '14 at 09:16
-
1@ChristopherCreutzig that means the segments are used for extending address space like PAE? – phuclv Mar 08 '14 at 10:06
-
@LưuVĩnhPhúc It’s been a long time that I’ve done assembly on anything 32 bit. The part I seem to remember is that you can save space for pointers pointing near to the code you have. Also, not all 32 bit architectures – certainly not all based on the x86 – use a flat memory model. See, e.g., http://www.tenouk.com/Bufferoverflowc/Bufferoverflow1a.html for some more discussion around this, although, as I said, it’s been a while and I cannot vouch for anything. – Christopher Creutzig Mar 09 '14 at 21:34
-
@Lưu Vĩnh Phúc The segmented architecture introduced with the 8088 and 8086 was predicated on the assumption that memory prices were high, so costs could be saved by keeping everything in 64K segments. It was a major headache to those of us programming low level code in that environment. It is rarely used now, but is still present in intel CPU's for the masochists among us. – pojo-guy Jul 04 '17 at 18:44
if you are compiling for a 64-bit machine, then it may be 8.

- 8,614
- 3
- 33
- 47
-
2While this is usually the case, it is not necessarily true. For example, if you're compiling on a 64-bit machine where the word size is 64-bits, then sizeof(char*) will probably be 1. Not to mention the more exotic pointer types in even common machines, as Eclipse and dmityugov write. – Kaz Dragon May 31 '13 at 08:01
-
@KazDragon, `sizeof(char*)==1` ? Are you sure? Don't you mean `size(char)==1`? – Aaron McDaid Nov 02 '13 at 10:34
-
3@AaronMcDaid I did indeed mean sizeof(char*). sizeof(char) is always 1. But if your machine word is 64-bits, and your development environment is implemented in such a way that CHAR_BITS=64, then it's possible that a pointer fits in the same space as a char and will hence also be 1. – Kaz Dragon Nov 04 '13 at 09:16
-
it's not true in [x32-abi](http://en.wikipedia.org/wiki/X32_ABI) https://sites.google.com/site/x32abi/ – phuclv Mar 05 '14 at 09:20
-
Just curious, @KazDragon can you give an example of a machine where CHAR_BITS=64? – rsaxvc Apr 12 '16 at 04:26
-
-
1@KazDragon I am building (very slowly, when not procrastinating) a machine with 16-bit words and no byte addressing. Although it can't run C anyway. – user253751 Dec 13 '19 at 16:01
-
@user253751: There are of course a number of off-the-shelf DSP chips like that. – Ben Voigt Feb 14 '20 at 16:42
Technically speaking, the C standard only guarantees that sizeof(char) == 1, and the rest is up to the implementation. But on modern x86 architectures (e.g. Intel/AMD chips) it's fairly predictable.
You've probably heard processors described as being 16-bit, 32-bit, 64-bit, etc. This usually means that the processor uses N-bits for integers. Since pointers store memory addresses, and memory addresses are integers, this effectively tells you how many bits are going to be used for pointers. sizeof is usually measured in bytes, so code compiled for 32-bit processors will report the size of pointers to be 4 (32 bits / 8 bits per byte), and code for 64-bit processors will report the size of pointers to be 8 (64 bits / 8 bits per byte). This is where the limitation of 4GB of RAM for 32-bit processors comes from -- if each memory address corresponds to a byte, to address more memory you need integers larger than 32-bits.

- 20,727
- 18
- 94
- 165
-
"You've probably heard processors described as being 16-bit, 32-bit, 64-bit, etc. This usually means that the processor uses N-bits for integers." -> I'm having a 64-bit machine but the sizeof(int) is 4 bytes. If your statement is true, how could this be possible?! – Sangeeth Saravanaraj Apr 17 '12 at 18:27
-
6@SangeethSaravanaraj: For backwards compatibility with 32-bit code, they decided to have int continue to be 4 bytes and require you to opt-in to using the 8 byte type by specifying 'long'. long is actually the native word size on x86-64. One way to see this is that typically compilers will pad your structs to make them word aligned (though there may be architectures where word size and alignment are unrelated), so if you make a struct with an int (32-bits) in it, and call sizeof() on it, if you get back 8 you know it's padding them to 64-bit word size. – Joseph Garvin Apr 17 '12 at 20:08
-
@SangeethSaravanaraj: Note that theoretically the native word size of the CPU and what the compiler decides 'int' is can be arbitrarily different, it's just it was convention for 'int' to be the native word size before x86-64 came around, where it's long to ease backwards compat. – Joseph Garvin Apr 17 '12 at 20:10
The size of the pointer basically depends on the architecture of the system in which it is implemented. For example the size of a pointer in 32 bit is 4 bytes (32 bit ) and 8 bytes(64 bit ) in a 64 bit machines. The bit types in a machine are nothing but memory address, that it can have. 32 bit machines can have 2^32
address space and 64 bit machines can have upto 2^64
address spaces. So a pointer (variable which points to a memory location) should be able to point to any of the memory address (2^32 for 32 bit and 2^64 for 64 bit
) that a machines holds.
Because of this reason we see the size of a pointer to be 4 bytes in 32 bit machine and 8 bytes in a 64 bit machine.

- 1,094
- 1
- 21
- 35
8 bit and 16 bit pointers are used in most low profile microcontrollers. That means every washing machine, micro, fridge, older TVs, and even cars.
You could say these have nothing to do with real world programming. But here is one real world example: Arduino with 1-2-4k ram (depending on chip) with 2 byte pointers.
It's recent, cheap, accessible for everyone and worths coding for.

- 5,129
- 1
- 17
- 22
In addition to the 16/32/64 bit differences even odder things can occur.
There have been machines where sizeof(int *) will be one value, probably 4 but where sizeof(char *) is larger. Machines that naturally address words instead of bytes have to "augment" character pointers to specify what portion of the word you really want in order to properly implement the C/C++ standard.
This is now very unusual as hardware designers have learned the value of byte addressability.

- 21,309
- 5
- 49
- 53
-
4The C compiler for Cray vector machines, such as the T90, do something similar. Hardware addresses are 8 bytes, and point to 8-byte words. `void*` and `char*` are handled in software, and are augmented with a 3-bit offset within the word -- but since there isn't actually a 64-bit address space, the offset is stored in the high-order 3 bits of the 64-bit word. So `char*` and `int*` are the same size, but have different internal representations -- and code that assumes that pointers are "really" just integers can fail badly. – Keith Thompson Jul 01 '12 at 01:49
In addition to what people have said about 64-bit (or whatever) systems, there are other kinds of pointer than pointer-to-object.
A pointer-to-member might be almost any size, depending how they're implemented by your compiler: they aren't necessarily even all the same size. Try a pointer-to-member of a POD class, and then a pointer-to-member inherited from one of the base classes of a class with multiple bases. What fun.

- 273,490
- 39
- 460
- 699
Size of pointer and int is 2 bytes in Turbo C compiler on windows 32 bit machine.
So size of pointer is compiler specific. But generally most of the compilers are implemented to support 4 byte pointer variable in 32 bit and 8 byte pointer variable in 64 bit machine).
So size of pointer is not same in all machines.

- 177
- 8
From what I recall, it's based on the size of a memory address. So on a system with a 32-bit address scheme, sizeof will return 4, since that's 4 bytes.

- 244
- 2
- 9
-
4There is no such requirement. There is not even a requirement that sizeof(unsigned int) == sizeof(signed int). The size of a pointer to an int will always be, by definition, sizeof(int *), to a char sizeof(char *) etc. Relying on any other assumption is a bad idea for portability. – Mihai Limbășan Dec 30 '08 at 11:15
-
1Could still return 2, if CHAR_BIT is 16. sizeof() counts in number of chars, not octets. – MSalters Apr 06 '09 at 13:56
-
5@Mihai: In C++ `sizeof (unsigned int) == sizeof (signed int)`, this requirement is found in 3.9.1/3. "For each of the standard signed integer types, there exists a corresponding (but different) standard unsigned integer type: `unsigned char`, `unsigned short int`, `unsigned int`, `unsigned long int`, and `unsigned long long int`, **each of which occupies the same amount of storage and has the same alignment requirements as the corresponding signed integer type**" – Ben Voigt Aug 31 '13 at 02:49
In general, sizeof(pretty much anything) will change when you compile on different platforms. On a 32 bit platform, pointers are always the same size. On other platforms (64 bit being the obvious example) this can change.

- 21,526
- 4
- 48
- 62
No, the size of a pointer may vary depending on the architecture. There are numerous exceptions.

- 26,961
- 9
- 82
- 99
In Win64 (Cygwin GCC 5.4), let's see the below example:
First, test the following struct:
struct list_node{
int a;
list_node* prev;
list_node* next;
};
struct test_struc{
char a, b;
};
The test code is below:
std::cout<<"sizeof(int): "<<sizeof(int)<<std::endl;
std::cout<<"sizeof(int*): "<<sizeof(int*)<<std::endl;
std::cout<<std::endl;
std::cout<<"sizeof(double): "<<sizeof(double)<<std::endl;
std::cout<<"sizeof(double*): "<<sizeof(double*)<<std::endl;
std::cout<<std::endl;
std::cout<<"sizeof(list_node): "<<sizeof(list_node)<<std::endl;
std::cout<<"sizeof(list_node*): "<<sizeof(list_node*)<<std::endl;
std::cout<<std::endl;
std::cout<<"sizeof(test_struc): "<<sizeof(test_struc)<<std::endl;
std::cout<<"sizeof(test_struc*): "<<sizeof(test_struc*)<<std::endl;
The output is below:
sizeof(int): 4
sizeof(int*): 8
sizeof(double): 8
sizeof(double*): 8
sizeof(list_node): 24
sizeof(list_node*): 8
sizeof(test_struc): 2
sizeof(test_struc*): 8
You can see that in 64-bit, sizeof(pointer)
is 8
.

- 27,532
- 16
- 147
- 165

- 5,931
- 3
- 49
- 56
The reason the size of your pointer is 4 bytes is because you are compiling for a 32-bit architecture. As FryGuy pointed out, on a 64-bit architecture you would see 8.

- 5,381
- 2
- 30
- 45
A pointer is just a container for an address. On a 32 bit machine, your address range is 32 bits, so a pointer will always be 4 bytes. On a 64 bit machine were you have an address range of 64 bits, a pointer will be 8 bytes.

- 122,712
- 22
- 185
- 265
-
2On a 32-bit machine with 32-bit bytes, sizeof(char *) could be 1. – Robert Gamble Dec 29 '08 at 23:28
-
1
-
2
Just for completeness and historic interest, in the 64bit world there were different platform conventions on the sizes of long and long long types, named LLP64 and LP64, mainly between Unix-type systems and Windows. An old standard named ILP64 also made int = 64-bit wide.
Microsoft maintained LLP64 where longlong = 64 bit wide, but long remained at 32, for easier porting.
Type ILP64 LP64 LLP64
char 8 8 8
short 16 16 16
int 64 32 32
long 64 64 32
long long 64 64 64
pointer 64 64 64