I have a char array; char students[] = "John Maria Elisa Hans" and a pointer *pStudents pointing to that array. I need to pass this pointer into a function and use there as a char array. What exactly I mean is the pointer needs to be dereferenced in the function to be used as a char array. Indeed, I tried some ways to dereference the pointer, but no result was achieved. How can I achieve it?
Note: passing pointer, not the char array is a must.
Related
malloc() function is said to return a null pointer or a pointer to the allocated space. Suppose for a string we make the statement:
char* ptr = malloc(size)
Isn't ptr a pointer that would point to a pointer?
Isn't :
char** ptr = malloc(size)
supposed to be the correct way to declare the pointer to char?
The compiler however doesn't give a warning when we do either, the warning it does give is for the format specifier if used.
How should we declare this and why? Also, how would char** be used?
No, 'ptr' would contain the pointer returned by 'malloc'. You are assigning the returned pointer, not taking its address.
The char * denotes a char pointer. Malloc will return a void * pointer (that will be automatically converted to whatever pointer you're trying to assign).
The char ** denotes a char * pointer. This is a pointer to a pointer.
If you think of a pointer as a map you have that char * is a map to a char, void * is a map to something mysterious and char ** is a map to another map that leads to a char. So
char* ptr = malloc(size);
Is the correct one, because you want a map to something, not a map to a map.
*ptr is a pointer to a char, which is often used to manage an array
or a string.
**ptr is a pointer to a pointer to a char, which is often used to
manage a matrix (array of arrays) or a string array.
Got this
char array1[10][10];
Is it possible to get address of array1 ? In which type could I stock it ?
Already tried the following:
char *hold[10][10];
hold = &array1;
But doesnt work, ideas?
What you have now is a 2D array of char *. You need some parenthesis in this type.
char (*hold)[10][10];
This is a pointer to a 2D array of type char[10][10] that you can assign &array to.
Typically you want to get the address of the first element, not a pointer to a 2D array. The first element is a char [10] (a 1D array), so you need
char (*hold)[10] = array1;
Notice array1 is converted to a pointer to the first element for the assignment. This is not recursively applied!
That way you can dereference the pointer exactly like for the original array:
hold[4][5]
For the char (*hold)[10][10] approach, the syntax is more complicated and not really ideomatic. Accessing an element of the array would require dereferencing the pointer first:
(*hold)[4][5]
Having the following code:
char data[2048];
And a function declared like this:
int f(char** data);
Can I safely call it like this:
f((char**)&data);
If I just use &data, the compiler issue the following warning:
warning C4047: 'function' : 'char **' differs in levels of indirection from 'char (*)[2048]'
No, you cannot.
data is an array. &data is a pointer to an array. It is not a pointer to a pointer. Despite the fact that data decays to a pointer in multiple contexts, it is not itself a pointer - taking the address gives you the address of the array.
If you want a pointer to a pointer to the array, you might try something like this:
char *pdata = data; // data decays to a pointer here
// (a pointer to the first element of the array)
f(&pdata); // Now &pdata is of type char ** (pointer to a pointer).
though, of course, what you actually need will depend on what your usecase is.
A pointer-to-pointer is not an array, nor is it a pointer to an array, nor should it be used to point at an array. Except for the special case where it can be used to point at the first item of an array of pointers, which is not the case here.
A function int f(char** data); cannot accept a char data[2048]; array as parameter. Either the array type needs to be changed, or the function needs to be rewritten.
Correct function alternatives would be:
int f (char* data);
int f (char data[2048]); // completely equivalent to char* data
int f (char (*data)[2048]); // array pointer, would require to pass the address of the array
As stated in this more detailed example:
While an array name may decay into a pointer, the address of the array does not decay into a pointer to a pointer. And why should it? What sense does it make to treat an array so?
Pointers to pointers are sometimes passed to modify the pointers (simple pointer arguments don't work here because C passes by value, which would only allow to modify what's pointed, not the pointer itself). Here's some imaginary code (won't compile):
void test(int** p)
{
*p = malloc ... /* retarget '*p' */
}
int main()
{
int arr[] = {30, 450, 14, 5};
int* ptr;
/* Fine!
** test will retarget ptr, and its new value
** will appear after this call.
*/
test(&ptr);
/* Makes no sense!
** You cannot retarget 'arr', since it's a
** constant label created by the compiler.
*/
test(&arr);
return 0;
}
You can do something like that.
char data[2048];
char *a=&data[0];
char **b=&a;
f(b);
I've just been helping someone out with some code. He had this:
char dataArray[10];
Then wanted to get a pointer to the start of the array. Rather than use:
&dataArray[0]
or just
dataArray
He used
&dataArray
Did he end up with a pointer to a pointer there? I'm not sure what &dataArray would give him.
&dataArray[0] is of type char *. That is a pointer to char.
dataArray is of type char[10]
&dataArray will be of type char (*)[10]. That is a pointer-to-array.
Apart from that, the value will be same, i.e., they point to the same address but their types need not be compatible.
None of them is a pointer-to-pointer here. They are just pointer with different types.
Note: Because the array decaying property, char [100] will decay to a char *, for example, when passed as an agument of a function.
dataArray and &dataArray[0] points to the address of the first index of the array so they are the same thing but &dataArray will point to the address of the whole array or we can say it will give the address where the whole 10 index array is located(as a whole)
I don't understand this part of code:
char *arrStr[3];
arrStr[0] = "hola"; //works
*(arrStr+1) = "guys"; //works
arrStr++; // doesn't work why?
char **arrStr2 = arrStr; //works
arrStr2++; //works
I don't understand why arrStr++ doesn't work while arrStr2 works.
This is strange because I'm doing the same thing, but in one case it works in the other not, why is that?
*arrStr[3] is an array of 3 pointers to char while **arrStr2 a pointer to a pointer to char. In
arrStr[0] = "hola";
arrStr is an array and array names are nonmodifiable l-values and hence you can't modify it. On the other hand modification can be done on arrStr as it is a pointer to pointer but not an array. Do remember that arrays are not pointers.
arrStr is an array of pointers, you can't modify an array name. arrStr++; won't compile.
arrStr2 is a pointer to a pointer, you can modify a pointer. And you should consider a better name, as it's not an array.
char *arrStr[3];
if you use the array name as a pointer,you must know that this pointer is a const pointer, so you can't do the ++ or -- operator, char *str = "ciao"; just declare a normal pointer, you can do every to it.