I'm a little bit lost on what this statement is doing. Is it making an array of X pointers? Or is it a pointer to an array of X chars? How much memory does it take on a 32-bit system?
If its the former, does it take 4*X bytes? If its the latter, is it just 1*X bytes?
This is a pointer which points to an array of X chars.
The C standard does not specify any particular size for a pointer. On common systems however, pointers are all the same size; so probably 4 bytes on your system.
X is part of the size of what is being pointed to, not the size of the pointer itself.
Related
My questions are how where are the pointer values stored and do they take up more space in memory than the things they point to. For example, if I have a 64 bit pointer which i use to point to a byte of information in memory; where is the value of the pointer stored and does it take up more space than the data itself?
An example of my question written in C
char data = 10;
char* charPointer = &data;
doesn't charPointer take up more space than the data since the pointer is 64 bit and the data is 8 bit?
PS: I'm currently trying to learn the basics of C.
where is the value of the pointer stored
The pointer's value is stored where you declared it to be stored; e.g. if you declared the pointer as a local variable, then it will be stored on the stack; OTOH if you allocated the pointer on the heap (or, more commonly, you included the pointer as a member-variable of an object that you allocated on the heap) then the pointer will be in the heap.
and does it take up more space than the data itself?
In this case, it does.
You can actually check for yourself how much space a value takes up:
printf("data takes up %zu bytes\n", sizeof(data));
printf("charPointer takes up %zu bytes\n", sizeof(charPointer));
If you are on a 64-bit machine, you should find that a pointer takes up 8 bytes, as you would expect.
The char that the pointer points to takes up one byte, but in many cases there will also be some padding bytes inserted to keep the alignment of the next item on the stack optimal for the CPU to access efficiently.
A pointer to a char takes more space than a char in practically every C implementation. (The C standard permits them to be the same size, but such implementations are at best rare and are more likely archaic or nonexistent.)
Nonetheless:
One may need a pointer to point to one of a selection of objects or to manage objects or to connect them in various ways.
A pointer may point to objects much larger than a char.
A pointer may point to the first of many elements in an array, so one pointer can provide access to many objects.
I'm writing my own memory allocater. I'm getting a pointer to mapped memory from mmap. From there, I want to be able to get a pointer to a different part of that mapped memory (like x bytes away from the current pointer). How can I do this? Memory management is very confusing to me.
mmap gives you a void* and C doesn't allow pointer arithmetic with those, but you can cast it to char* and then just add the number of bytes you want, e.g. mypointer + 16.
If you cast the pointer to a larger type (like int*), pointer arithmetic adds multiples of the size of that type. For example, if you add 16 to an int*, you're adding enough bytes for 16 int values (so 64 bytes, assuming sizeof(int) is 4).
AFAIK, the size occupied by any type of pointer is the same on a given architecture. That is, the only difference between different types of pointers is what will happen when we use an operation such as ptr++ or ptr-- on the pointer.
As an example:
char *cptr;
int *iptr;
occupy the same amount of memory (such as 4 bytes, or 8 bytes or something else). However, the difference is what will happen when we use the increment (or decrement) operator on the pointers. cptr++ will increment cptr by 1, while iptr++ will increase iptr by 4 (depending on the architecture, it can be a different value than 4 as well).
The Question
My question is, are there any differences between:
char **cdptr;
int **idptr;
(Assume that for the machine under mention, pointers have a size of 4 bytes)
Since both are pointers, both will occupy the same amount of space: 4 bytes. Also, since both point to something that occupy the same size (again, 4 bytes), operations char cdptr++ and int idptr++ will work exactly the same on these two pointers (incrementing them by 4 respectively).
So, do different types of higher order pointers have any differences?
Formally speaking, yes, these pointer types are different. They have different types, types which are important to the programmer and which the compiler keeps intimate track of. You can prove they're different by trying to compile
char **cdptr;
int **idptr = NULL;
cdptr = idptr;
Your compiler will complain. (gcc says "assignment from incompatible pointer type".) You can also convince yourself that they're different by noticing what happens when you indirect on them: cdptr[1][2] is of course a char, while idptr[1][2] is an int.
Now, it's true, since sizeof(*cdptr) almost certainly equals sizeof(*idptr), pointer arithmetic like cdptr++ and idptr++ will generate the same code. But this doesn't strike me as a terribly useful fact -- it's about as interesting as observing that if we declare
int *iptr;
char **cdptr;
we get the same code for iptr++ and cdptr++ on a machine where ints and pointers happen to be the same size. But this doesn't tell us anything we can use while writing C programs. "Generate the same code when incremented" does not equal "are the same".
Basically, in C language, a pointer is more than a memory address. It is a memory address AND a type.
The type is needed when you use pointer arithmetics. For example: ptr + 2 means that you shift the current position of the pointer in memory by 2 sizeof(pointed type by ptr).
So, a pointer of pointer differ from a simple pointer by its type... That's all.
char *c = (char *)malloc(30*sizeof(char));
printf("%lu \n",sizeof(c));
In the above code I am trying to print the size of 'c'. No matter what number I give instead of '30' in the code, I get the sizeof(c) as 8.
What is the problem? How can I determine the size of an array?
Is length and size the same for an array?
At the moment you are asking for the size of a pointer which on a 64 bits machine is 8 bytes. Since this is a malloc and not a real array, you can't retrieve the size of the buffer allocated through c.
If c was declared as
char c[30];
You could determine size with
size_t size = sizeof(c)/sizeof(c[0])
But to be honest if I had to do that, I would just #define the array size even though the size calculation would be stripped out at compilation. It makes the code clearer in my opinion.
You are printing the size of a char * which in your system is 8.
If you want to know the amount of memory that was "malloc"ed you must store it somewhere. In your case your should store the 30 for future use if you are going to need it.
sizeof(c) means give me the size of the variable c. Since c is a pointer it's giving you back the number of bytes that the pointer takes up in memory. The fact you're seeing 8 suggests you're compiling for 64bit. On a 32bit built it would be 4.
It's your job to remember the size of the thing you've allocated. After all, you asked for an amount of memory, so you do know how much you allocated! In your case, size_t size = 30*sizeof(char) will give you the amount you've allocated.
sizeof is an operator, not a function, thus the compiler creates the code equivalent to something like sizeof(char *) and pointer of a char (depending on the architecture of course) is of 8 bytes.
Actually sizeof(*c) will return 1. The size of a mallocced buffer cannot be determined compile time (which is what sizeof does).
You're getting the size of the variable c, not the size of the memory region it points to. There's no way to get the size of an array inside a function because it always decays to pointer. You must store the size yourself. If you've passed the size to malloc then why can't you store that size to a variable?
What is wrong with this statement? It doesn't copy right.
memcpy(new_board1, board, sizeof(board));
memcpy accepts two memory addresses in form of pointers (destination and source) and the number of bytes to be copied. Now, sizeof doesn't return the size of the memory block a pointer points to, but the size of the pointer itself - either 4 bytes on a 32bit OS, or 8 bytes on a 64bit OS.
sizeof(board) gives you the size of the pointer itself, not the size of whatever it points at. You should replace it by the actual number of bytes you want to copy from board to new_board1. Without knowing how boardand new_board1 are declared, I cannot help you find that number.