Hi,
I read that to declare an array in C, one needs to specify the type of the elements and the number of elements required by an array as follows: type arrayName [ arraySize ];
However, I see many times the following: int[] arr;
or int[][] arr;
How come these are valid?
I tried it myself and it resulted in an error.
I also tried it inside function's argument, and also got an error.
(working with DEV-C++).
Thank you for any help.
---EDIT---
I'd appreciate it if you could also comment on the following:
when declaring a pointer: char *p;
it points on a garbage.
But when declaring + initializing a pointer: char *p = "text";
does it allocate 5 bytes in memory for p? (text + '\0' are 5 bytes)
It allocates 5 bytes of memory somewhere else and puts "text"\0 into this memory. It makes sure that this memory is initalized with the "text"\0 before the program runs. Then it allocates memory for the pointer p (whatever the size of the pointer is). Then it initializes p to point to the memory allocated for "text"\o.
I want to point out one important difference between arrays and pointers.
char *p = "text";
As said, this allocates 5 bytes for the string and some bytes for the pointer.. and then initializes the pointer to point to the start of the string.
Now, If you say: sizeof(p);
The size of the pointer variable is returned, which depends on the machine you are programming.
If you declare the variable as an array: char s[] = "text";
This allocates an array for 5 chars and initializes it to {'t', 'e', 'x', 't', '\0'}
If you now say: sizeof(s);
The length of the array is returned (5 bytes).
Arrays can be used as pointers, but arrays and pointers are not exactly the same. Using array in this case actually saves you memory, because no extra pointers are allocated. Also accessing the array is probably more efficient.
void** is a void pointer to a pointer.. This means you can have several pointers allocated to blocks of memory, the pointer pointer is used to point to one of these memory block pointers...
Are you familiar with normal pointers... try reading about pointer arrays first, so you can get your head round it...
No.... the function takes a pointer, allocates against that pointer, then returns a pointer to that pointer..
I agree you only need a pointer to that specific allocation, but library functions have to cater for all and sundry... this is why we write our own functions that are specific to us...
EDIT... You can still use the pointer passed to the allocating function. ie P1 and access the memory..
It may give a warning, but in this case the the void** is cast to void* when it is returned.
In another words, inside the function variable p2 is treated as void**, but the returned value is treated as void*. This should work.
I don't have the interest of finding out how the whole memory allocation etc works. They have some data-structure-system that requires pointers to be manipulated this way (maybe to ensure portability; Different systems have different size pointers etc.. using pointers to pointers eliminates the need to know the exact size of a pointer).
All pointers are the same size in the same system. Void pointer points to a memory address which contents is unknown. Void pointer does not mean that the pointer points to "empty" or "null".
p2 here is a void**.
So, p2[-1]
is the same as *(p2-1)
But, the actual memory location value is decremented by sizeof(void*).
And... you are right. If you have void* p1, then you can not say p1[-1], because the sizeof(void) is unknown and result compile error (at least it should, some compilers do not fail).
Manipulations like this are difficult to understand without understanding and studying the underlying data structure (or algorithm) first.
P2 doesn't point to void!!! The reason P1 and P2 are declared void is you have no idea the size of the array it points at.
The idea behind the size of the pointer is so you can increment or decrement it.
void * p; just means initialize a pointer that I can point to anything.. The code shows you that to increment a void pointer you need to workout the size of the thing its pointing to.... a void** pointer is the same size... you can increment and decrement through the allocations easier....
Yeah.. I have a habit editing my own posts a while after posting
To summarize
sizeof(void*) // This is the size of pointer, because void* is a pointer (to unknown content)
sizeof(void) // This is the size of unknown content.. should not compile
P2 doesn't point to void!!! The reason P1 and P2 are declared void is you have no idea the size of the array it points at.
The idea behind the size of the pointer is so you can increment or decrement it.
void * p; just means initialize a pointer that I can point to anything.. The code shows you that to increment a void pointer you need to workout the size of the thing its pointing to.... a void** pointer is the same size... you can increment and decrement through the allocations easier....
Yes. The "aligned_malloc" wastes some of the memory returned by the standard "malloc". So, they need to store that original pointer somewhere known place, so that they can later free the whole memory. And what could be better place to store that pointer than "-1" from the aligned pointer.