3

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;
}
4
  • 3
    C or C++? They are two different languages, and it's especially important in cases like this where one language has a feature what will help directly, while the other language is missing that feature. Commented Sep 6, 2017 at 3:49
  • However, since the code itself is really plain C, and that's what you mention explicitly in the title, you should search for and do some research about emulating pass by reference in C. Commented Sep 6, 2017 at 3:51
  • The code you show doesn't compile – that makes it hard to deconstruct usefully to explain what's going wrong. Commented Sep 6, 2017 at 3:54
  • When you say "the variable num remains at 0", you mean num_results, right? Since that's what you are printing. Commented Sep 6, 2017 at 3:56

5 Answers 5

7

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:

  1. You probably have this in your full code, but don't forget to #include <stdio.h> to use printf() and to #include <stdlib.h> to use malloc()
  2. Your function 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;
}
Sign up to request clarification or add additional context in comments.

1 Comment

I'm also assuming OP really wants to allocate memory inside the set function.
1
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;
}

Comments

1

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?

Comments

0

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;
}

Comments

0

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.

6 Comments

Simply finding a way to make the code work doesn't help the OP to understand what he did wrong.
You're right that the original code won't compile. It isn't clear why this is an improvement, or how your design decisions (ignoring results parameter to set(), for example) are justified.
completely agree with you.
Please note that you are expected to disclose your affiliation when you are promoting a site by showing it at work in answers. You can add the information to your profile, and you should probably note it in each answer. Please check the help centre for information (for example, Promotion — How to not be a spammer).
Yes, it's my website and just released today. I saw many people kept asking why my code cause seg-fault, and these causes apparently can be reported automatically. Any feedback is highly appreciated. Profile updated.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.