Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is size_t better?

The title is actually a bit misleading, but I wanted to keep it short. I've read about why I should use size_t and I often found statements like this:

size_t is guaranteed to be able to express the maximum size of any object, including any array

I don't really understand what that means. Is there some kind of cap on how much memory you can allocate at once and size_t is guaranteed to be large enough to count every byte in that memory block?

Follow-up question:
What determines how much memory can be allocated?

like image 791
Paul Manta Avatar asked Oct 21 '11 13:10

Paul Manta


3 Answers

Let's say the biggest object your compiler/platform can have is 4 gb. size_t then is 32 bit. Now let's say you recompile your program on a 64 bit platform able to support objects of size 2^43 - 1. size_t will be at least 43 bit long (but normally it will be 64 bit at this point). The point is that you only have to recompile the program. You don't have to change all your ints to long (if int is 32 bit and long is 64 bit) or from int32_t to int64_t. (if you are asking yourself why 43 bit, let's say that Windows Server 2008 R2 64bit doesn't support objects of size 2^63 nor objects of size 2^62... It supports 8 TB of addressable space... So 43 bit!)

Many programs written for Windows considered a pointer to be as much big as a DWORD (a 32 bit unsigned integer). These programs can't be recompiled on 64 bit without rewriting large swats of code. Had they used DWORD_PTR (an unsigned value guaranteed to be as much big as necessary to contain a pointer) they wouldn't have had this problem.

The size_t "point" is the similar. but different!

size_t isn't guaranteed to be able to contain a pointer!!
(the DWORD_PTR of Microsoft Windows is)

This, in general, is illegal:

void *p = ...
size_t p2 = (size_t)p;

For example, on the old DOS "platform", the maximum size of an object was 64k, so size_t needed to be 16 bit BUT a far pointer needed to be at least 20 bit, because the 8086 had a memory space of 1 mb (in the end a far pointer was 16 + 16 bit, because the memory of an 8086 was segmented)

like image 83
xanatos Avatar answered Sep 23 '22 01:09

xanatos


Basically it means that size_t, is guaranteed to be large enough to index any array and get the size of any data type.

It is preferred over using just int, because the size of int and other integer types can be smaller than what can be indexed. For example int is usually 32-bits long which is not enough to index large arrays on 64-bit machines. (This is actually a very common problem when porting programs to 64-bit.)

like image 44
Mysticial Avatar answered Sep 23 '22 01:09

Mysticial


That is exactly the reason. The maximum size of any object in a given programming language is determined by a combination of the OS, the CPU architecture and the compiler/linker in use.

size_t is defined to be big enough to hold the size value of the largest possible object.

This usually means that size_t is typedef'ed to be the same as the largest int type available. So on a 32 bit environment it would typically be 4 bytes and in a 64 bit system 8 bytes.

like image 43
Tonny Avatar answered Sep 24 '22 01:09

Tonny