问题
As I know, when a pointer is passed into a function, it becomes merely a copy of the real pointer. Now, I want the real pointer to be changed without having to return a pointer from a function. For example:
int *ptr;
void allocateMemory(int *pointer)
{
pointer = malloc(sizeof(int));
}
allocateMemory(ptr);
Another thing, which is, how can I allocate memory to 2 or more dimensional arrays? Not by subscript, but by pointer arithmetic. Is this:
int array[2][3];
array[2][1] = 10;
the same as:
int **array;
*(*(array+2)+1) = 10
Also, why do I have to pass in the memory address of a pointer to a function, not the actual pointer itself. For example:
int *a;
why not:
allocateMemory(*a)
but
allocateMemory(a)
I know I always have to do this, but I really don't understand why. Please explain to me.
The last thing is, in a pointer like this:
int *a;
Is a the address of the memory containing the actual value, or the memory address of the pointer? I always think a is the memory address of the actual value it is pointing, but I am not sure about this. By the way, when printing such pointer like this:
printf("Is this address of integer it is pointing to?%p\n",a);
printf("Is this address of the pointer itself?%p\n",&a);
回答1:
I'll try to tackle these one at a time:
Now, I want the real pointer to be changed without having to return a pointer from a function.
You need to use one more layer of indirection:
int *ptr; void allocateMemory(int **pointer) { *pointer = malloc(sizeof(int)); } allocateMemory(&ptr);Here is a good explanation from the comp.lang.c FAQ.
Another thing, which is, how can I allocate memory to 2 or more dimensional arrays?
One allocation for the first dimension, and then a loop of allocations for the other dimension:
int **x = malloc(sizeof(int *) * 2); for (i = 0; i < 2; i++) x[i] = malloc(sizeof(int) * 3);Again, here is link to this exact question from the comp.lang.c FAQ.
Is this:
int array[2][3]; array[2][1] = 10;the same as:
int **array; *(*(array+2)+1) = 10ABSOLUTELY NOT. Pointers and arrays are different. You can sometimes use them interchangeably, however. Check out these questions from the comp.lang.c FAQ.
Also, why do I have to pass in the memory address of a pointer to a function, not the actual pointer itself?
why not:
allocateMemory(*a)It's two things - C doesn't have pass-by-reference, except where you implement it yourself by passing pointers, and in this case also because
aisn't initialized yet - if you were to dereference it, you would cause undefined behaviour. This problem is a similar case to this one, found in the comp.lang.c FAQ.int *a;Is a the address of the memory containing the actual value, or the memory address of the pointer?
That question doesn't really make sense to me, but I'll try to explain.
a(when correctly initialized - your example here is not) is an address (the pointer itself).*ais the object being pointed to - in this case that would be anint.By the way, when printing such pointer like this:
printf("Is this address of integer it is pointing to?%p\n",a); printf("Is this address of the pointer itself?%p\n",&a);Correct in both cases.
回答2:
To answer your first question, you need to pass a pointer to a pointer. (int**)
To answer your second question, you can use that syntax to access a location in an existing array.
However, a nested array (int[][]) is not the same as a pointer to a pointer (int**)
To answer your third question:
Writing a passes the value of the variable a, which is a memory address.
Writing *a passes the value pointed to by the variable, which is an actual value, not a memory address.
If the function takes a pointer, that means it wants an address, not a value.
Therefore, you need to pass a, not *a.
Had a been a pointer to a pointer (int**), you would pass *a, not **a.
回答3:
Your first question:
you could pass a pointer's address:
void allocateMemory(int **pointer) {
*pointer = malloc(sizeof(int));
}
int *ptr;
allocateMemory(&ptr);
or you can return a pointer value:
int *allocateMemory() {
return malloc(sizeof(int));
}
int *ptr = mallocateMemory();
回答4:
I think you're a little confused about what a pointer actually is.
A pointer is just variable whose value represents an address in memory. So when we say that int *p is pointer to an integer, that just means p is a variable that holds a number that is the memory address of an int.
If you want a function to allocate a buffer of integers and change the value in the variable p, that function needs to know where in memory p is stored. So you have to give it a pointer to p (i.e., the memory address of p), which itself is a pointer to an integer, so what the function needs is a pointer to a pointer to an integer (i.e., a memory address where the function should store a number, which in turn is the memory address of the integers the function allocated), so
void allocateIntBuffer(int **pp)
{
// by doing "*pp = whatever" you're telling the compiler to store
// "whatever" not in the pp variable but in the memory address that
// the pp variable is holding.
*pp = malloc(...);
}
// call it like
int *p;
allocateIntBuffer(&p);
I think the key to your questions is to understand that there is nothing special about pointer variables. A pointer is a variable like any other, only that the value stored in that variable is used to represent a position in memory.
回答5:
Note that returning a pointer or forcing the caller to move the pointer in an out of a void * temp variable is the only way you can make use of the void * type to allow your function to work with different pointer types. char **, int **, etc. are not convertible to void **. As such, I would advise against what you're trying to do, and instead use the return value for functions that need to update a pointer, unless your function by design only works with a specific type. In particular, simple malloc wrappers that try to change the interface to pass pointer-to-pointer types are inherently broken.
来源:https://stackoverflow.com/questions/4660321/store-pointer-value