Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Store pointer value

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);
like image 281
Amumu Avatar asked Dec 22 '22 19:12

Amumu


2 Answers

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.

like image 37
SLaks Avatar answered Jan 06 '23 20:01

SLaks


I'll try to tackle these one at a time:

  1. 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.

  2. 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.

  3. Is this:

    int array[2][3];
    array[2][1] = 10;
    

    the same as:

    int **array;
    *(*(array+2)+1) = 10
    

    ABSOLUTELY NOT. Pointers and arrays are different. You can sometimes use them interchangeably, however. Check out these questions from the comp.lang.c FAQ.

  4. 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 a isn'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.

  5. 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). *a is the object being pointed to - in this case that would be an int.

  6. 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.

like image 83
Carl Norum Avatar answered Jan 06 '23 20:01

Carl Norum