After a long time spent on making this code work, can someone explain to me why I need 2 stars when I pass a pointer to a string as an argument to the function? A pointer, by definition, keeps the address to a memory where a certain variable will be placed. So it is a variable that has got its own address and under this address is address to another variable. Okay. So if I pass a pointer to a function I use ampersand because I must pass the pointer address to the function. Fine. But then what happens. The function receives the information where in the memory is located this pointer. Okay. This is what I understand. What I do not understand is why I need two stars when I define the function and its argument. I am passing a pointer to a char variable. Why not void wpisuj(char * w). Why wpisuj(char** w). Memory allocation is understandeable to me - I reserved memory with malloc and malloc returns address of this memory, so I place this address as the value of the variable w. And then again something I do not understand, if *w is the pointer and keeps the address of the newly created place in the memory, why I use *w to place there a string. Should it not be *(*w)? Since *w is the address of the reserved memory, then *(*w) is the contents of this memory.
Summing up. What I do not understand is: 1) why wpisuj (char **w) instead of wpisuj (char *w) 2) why strcpy(w, bufor) instead of strcpy((*w), bufor)
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
# define SIZE 256
void wpisuj(char** pw){
char bufor[256];
scanf("%s", bufor);
int l;
l=strlen(bufor)+1;
*pw=(char*)malloc(l*sizeof(char));
strcpy(*pw, bufor);
}
int main(){
char* w;
wpisuj(&w);
printf("%s", w);
return 0;
}
And if I may also ask about freeing the memory. Am I correct in thinking that this is the corect amount of stars (as in the code below):
void free_memory(char **w){
free(*w);
}
but, if I freed memory in main() I would have:
int main(){
w=malloc(sizeof(buffer)+sizeof(char));
/* some code before */
free(w);
}
To make it clear consider the following simple program
#include <stdio.h>
void f( int x )
{
x = x + 20;
}
int main(void)
{
int x = 10;
printf( "Before the call f( x ) x = %d\n", x );
f( x );
printf( "After the call f( x ) x = %d\n", x );
return 0;
}
The output will be
Before the call f( x ) x = 10
After the call f( x ) x = 10
As you see x
was not changed in the function f
because the function deals with a copy of the value of the object x
defined in main
.
However if you will rewrite the function the following way
#include <stdio.h>
void f( int *x )
{
*x = *x + 20;
}
int main(void)
{
int x = 10;
printf( "Before the call f( x ) x = %d\n", x );
f( &x );
printf( "After the call f( x ) x = %d\n", x );
return 0;
}
then in this case the output will be
Before the call f( x ) x = 10
After the call f( x ) x = 30
because we passed to the function the address of the original object x
and inside the function the original object itself was changed due to dereferencing the passed pointer.
The same is valid with the pointer from your post.
If you will define a pointer
char *p;
in main and pass it as an argument to function
void f( char *p );
then the function will deal with a copy of the original object (pointer). Any changes of the copy do not influence on the original pointer. So as in the first example you should pass a pointer to this pointer that is the function should be declared like
void f( char **p );
and you have to call it like
f( &p );