0

I managed to put the value in the pointer while in the function, However when i come back to the main i just dont get the values. Where am i wrong? sending parameters wrong? wrong allocation? Here's the code:

bool wc(int* nlines, int* nwords, int* nchars)
{
    int lines=5,chars=6,words=7;
    nchars = (int *) malloc(chars*sizeof(int));
    *nchars = chars;
    nlines = (int *) malloc(lines*sizeof(int));
    *nlines = lines;
    nwords = (int *) malloc(words*sizeof(int));
    *nwords = words;

}
int main() {
    int* chars; int* words; int* lines;
    int res = wc(&lines,&words,&chars);
    printf("%d %d %d\n",chars,lines,words);
    return 0;
}
noor napso
  • 113
  • 5
  • [C and pointer in a function - changes do not save](https://stackoverflow.com/questions/14143274/c-and-pointer-in-a-function-changes-do-not-save) Not really sure why you're using `malloc` for this though. You're just storing one value in each parameter and, assuming `lines`, `words`, and `chars` are declared as `int` they already point to space for that. If you delete the `malloc` lines it should work properly. If this was a [mcve] we'd know for sure. – Retired Ninja Dec 06 '21 at 08:46
  • @RetiredNinja i dont know what's the problem so i just allocated. I tried without doing that too. btw i have no option to return a pointer, not sure if what u linked helps me. – noor napso Dec 06 '21 at 08:50
  • In wc, nlines, nwords, nchar are local variables initialized with the addresses of some variables of main(), their content are replaced by addresses of dynamic buffers (locally in wc with malloc), then you write in these dynamic buffers (so not in main variables). So the high level variables are unchanged. – Eric Marchand Dec 06 '21 at 08:51
  • Worth noting too that your function says it will return a value but it doesn't. That causes undefined behavior. – Retired Ninja Dec 06 '21 at 08:52
  • @RetiredNinja yea i didnt add that part where i return true since it wasnt relevant to my problem. – noor napso Dec 06 '21 at 08:53
  • Edited the code... – noor napso Dec 06 '21 at 08:54
  • It is relevant because without it the program is broken. This works fine: https://ideone.com/9e5MKX – Retired Ninja Dec 06 '21 at 08:54
  • @RetiredNinja in my edited code, the problem is with how i created the variables in main? u created int and i created pointers. – noor napso Dec 06 '21 at 08:57
  • The problem is that the malloc() replace the pointers matching main variables initially by addresses of dynamic buffers, with a local scope (wc). So when you assign variables you don't change the main variables but the dynamic buffers. – Eric Marchand Dec 06 '21 at 08:58
  • `int* chars; int* words; int* lines;` is wrong in several ways. Those pointers don't point to anything, they are uninitialized. That would be okay if you planned to allocate then in the function, but the function expects `int*` where `&chars` and the rest are `int**` and that's relevant to being able to allocate them in the function and the point of the question I linked earlier. If you fix that and allocate space for 1 `int` in the function you're almost there, but then the arguments to `printf` are wrong, they would need to be `*chars, *lines, *words`. – Retired Ninja Dec 06 '21 at 08:59
  • You are passing wrong type of parameters. While you claim your function takes `int *` you pass `int**` which does not match. Your compiler should complain about that. Same as for the missing return value. You should increase warning level. For GCC you can use `-Wall -Wextra`. If you already got these warnings, don't just ignore them. – Gerhardh Dec 06 '21 at 09:06

2 Answers2

1

If all you want to do is be able to set 3 int values inside a function then this is how I would so it.

#include <stdio.h>
#include <stdbool.h>
 
bool wc(int* nlines, int* nwords, int* nchars)
{
    int lines=5,chars=6,words=7;
    *nchars = chars;
    *nlines = lines;
    *nwords = words;
    return true;
}
int main() {
    int lines = 0;
    int words = 0;
    int chars = 0;
    int res = wc(&lines,&words,&chars);
    printf("%d %d %d\n",chars,lines,words);
    return 0;
}

If for some reason you must use pointers as shown in your example then this will do what you want.

#include <stdio.h>
#include <stdbool.h>
 
bool wc(int** nlines, int** nwords, int** nchars)
{
    int lines=5,chars=6,words=7;
    *nchars = malloc(sizeof(int));
    **nchars = chars;
    *nlines = malloc(sizeof(int));
    **nlines = lines;
    *nwords = malloc(sizeof(int));
    **nwords = words;
    return true;
}
int main() {
    int* chars; int* words; int* lines;
    int res = wc(&lines,&words,&chars);
    printf("%d %d %d\n",*chars,*lines,*words);
    free(chars);
    free(words);
    free(lines);
    return 0;
}

As you can see this just means you need to add a bunch more * all over the place.

Retired Ninja
  • 4,785
  • 3
  • 25
  • 35
  • 1
    Thanks, I think i finally managed to make it work even though mallocing the nwords causing sigmentation fail for no reason at all. – noor napso Dec 06 '21 at 09:15
0

In C function input variables are passed by value, not reference. So when you assign them locally, the value in the caller scope is unaffected. E.g.

void foo(int a) {
  a = 5;
}

int main() {
  int b = 3;
  foo(b);
  // here, b is still 3
}

This is exactly what you are doing in your example, though your variables are not int, but int*.

If your input variable is a pointer though, you can change the memory that the variable points to, and this will obviously reflect in the calling scope. E.g.

void foo(int *a) {
  *a = 5;
}

int main() {
  int b = 3;
  foo(&b);
  // here, b is 5
}

In your case, you want to allocate pointers, so you want your function signature to be a pointer to a pointer. E.g.

void foo(int **a) {
  *a = malloc(sizeof(int));
}

int main() {
  int* b = NULL;
  foo(&b);
  // here, b is allocated to a valid heap area
  free(b);
}
Zeppe
  • 205
  • 2
  • 4