Reputation: 31
This variable num remains at 0. I suspect this is because I am passing in a NULL pointer, but I am constrained to the main (and parameters) as is. How do I adjust the content of the helper function to update num correctly?
int main(void) {
int * num_results = NULL;
int num = 4;
set(num_results, num);
printf(“%d\n”, *num_results);
return 0;
}
void set(int * results,num){
num_results = malloc(sizeof(int));
*num_results = num;
}
Upvotes: 3
Views: 15578
Reputation: 401
Your code won't compile. Compiler error messages will tell you how to fix them. Here is a fixed one.
#include<stdlib.h>
#include<stdio.h>
int * num_results = NULL;
void set(int * results, int num){
num_results = malloc(sizeof(int));
*num_results = num;
}
int main(void) {
int num = 4;
set(num_results, num);
printf("%d\n", *num_results);
return 0;
}
For the sake of learning it, you can look at the compilation error messages here and try to fix it by yourself:https://segfault.stensal.com/a/XWfv8rxCJHVtAuRQ
Disclaimer: I built stensal.io as a tool to catch memory issues.
Upvotes: 0
Reputation: 180266
How do I adjust the content of the helper function to update num correctly?
That seems the wrong question, as your set()
function seems intended to copy the value of num
elsewhere, not to update num
itself.
One of your problems is where to copy it. Presently, you allocate some memory for that dynamically, and copy it there. That's fine as far as it goes, but the pointer to the allocated memory is not conveyed back to the caller. This is because all C functions pass arguments by value, and in particular, your main()
passes the first argument of set()
by value (a value of type int *
). Modifying the function's copy does not affect its caller's copy -- that's what pass-by-value is all about.
You may be overlooking a simple fact: dynamic allocation is not the only way to obtain a valid pointer value, nor even the the most important or common. When you see a pointer, you should not automatically go looking for malloc()
. You can very easily get a pointer from an array, but perhaps even more importantly, you can get a pointer value by applying the address-of operator (&
).
For your set()
function to do work that its caller can see without resorting to global variables or changing its signature, the caller must pass as the first parameter a valid pointer to an object that the caller can access, such as one of its own local variables. The pointer is passed by value so the function gets a copy, but it's a copy: it points to the same object that the caller's pointer did. The set()
function can therefore modify the pointed-to object via its copy of the pointer to it.
So suppose your main()
declared its own local variable result
, an int
. What do you suppose it could do with &result
?
Upvotes: 1
Reputation: 4044
set(num_results, num);
Here NULL is getting passed to results
variable in set()
, when you allocate memory to results
, NULL is getting replaced by valid memory address, but you need to understand it will be held in results
variable only as its a local variable to set()
You should either pass address of num_results
to set()
so that memory allocated in set()
is retained in main()
, or just allocate memory to num_results
in main function then pass it to set()
as done below:
#include <stdio.h>
int main() {
int *num_results = NULL;
int num = 4;
num_results = malloc(sizeof(int));
set(num_results, num);
printf("%d\n", *num_results);
return 0;
}
void set(int *results,int num){
*results = num;
}
Another example would be:
#include <stdio.h>
#include <stdlib.h>
void set(int **r, int num);
int main() {
int *num_results = NULL;
int num = 4;
/*num_results = malloc(sizeof(int));*/
set(&num_results, num);
printf("%d\n", *num_results);
return 0;
}
void set(int **results,int num){
*results = malloc(sizeof(int));
*(*results) = num;
}
Upvotes: 1
Reputation: 979
I'm going to guess what you really mean with your question and try to give a decent answer.
I guess you want to change num_results
to be equal to num
by passing it to the function set
as a pointer, and I can see a few mistakes you've made:
#include <stdio.h>
to use printf()
and to #include <stdlib.h>
to use malloc()
set()
should be declared before main()
, you can do this by declaring a prototype before main()
or simply defining the set()
function before main()
.Now let's go to your solution: you want to pass the num_results
as a parameter to a function, allocate some memory and assign the address to num_results
and then update the value to the one in num
.
When you pass an int *
as a parameter, I guess you already know that by passing int
you are simply giving a copy of what is inside an int
variable. This works the same way with an int *
, you are not passing a reference to num_results
so that you can update the address of the pointer, you are passing a copy of the current address, NULL
, which will not be modified. What could be modified is what is inside of the current address, but the current address is NULL
, so not can really be modified.
Since you want to allocate memory and assign its address to num_results
, you must pass a pointer to a pointer, so you are passing the address of where your int*
variable is being kept and where you can actually change it.
This way, your function should look like void set(int ** results, int num)
and you should call it with set(&num_results, num)
, so you are passing a reference to num_results, where you can change the address it points to, currently NULL
and then the address returned by malloc()
.
You'd also have to change the body of your function, because you're now using an int **
, you want to assign the new address to *results
, because results == &num_results
, and assign num to **results
, because *results = num_results
.
I hope my explanation is not very confusing and hopefully someone can explain it better with another answer or by editing mine. Final code:
#include <stdio.h>
#include <stdlib.h>
void set(int ** results, int num){
*results = malloc(sizeof(int));
**results = num;
}
int main(void) {
int * num_results = NULL;
int num = 4;
set(&num_results, num);
printf("%d\n", *num_results);
return 0;
}
Upvotes: 7
Reputation: 163
In your helper function you should refer to the first parameter name results instead of num_results. Your helper function should be like:
void set(int * results, int num){
results = malloc(sizeof(int));
*results = num;
}
Upvotes: 0