1

I am an C beginner and I do not understand why I am getting an error here. I was taught that a pointer survives a function with malloc, but here I get a code dumped.

I need to get this and can't find anything on the Internet. I know that you can do it completely different, but I didn't want to use global variables or a pointer to pointer. I'd love to learn about malloc!

#include <stdio.h>
#include <stdlib.h>

void doStuff();

void doStuff(int *a) {
    a = malloc(sizeof(int));
    *a = 3;
    printf("%d \n", *a);
};

int main() {
    int *a;

    doStuff(a);
    printf("%d", *a);

    free(a);
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
Newwboi
  • 13
  • 2
  • 1
    Does this answer your question? [C Programming: malloc() inside another function](https://stackoverflow.com/questions/2838038/c-programming-malloc-inside-another-function) – Francesco May 17 '20 at 13:44
  • thanks for the quick answer. i am looking for a solution without pointer to pointer.I have read that you can use malloc and the pointer survive but thats not the case. Thats confusing – Newwboi May 17 '20 at 13:46
  • "An exception is when you can guarantee that the location pointed to will survive even after the function exits, e.g. when the location is dynamically allocated using malloc (see below) or when the local variable is declared static." (Source: https://www.cs.yale.edu/homes/aspnes/pinewiki/C(2f)Pointers.html) – Newwboi May 17 '20 at 13:53
  • I have referenced it for you :) – Newwboi May 17 '20 at 13:53

4 Answers4

1

You've fallen into the classic c function argument trap. Read this to understand "pass by value" in c. It's very important that you read and understand everything in that link, but the simple version is that the value you assigned to a does not survive outside the function. It's important to note that using malloc here is irrelevant, it's how you're passing the argument that's causing the problem.

The reference you included in your comment shows how you would properly do this in the malloc section:

#include <stdlib.h>

/* allocate and return a new integer array with n elements */
/* calls abort() if there isn't enough space */
int *
makeIntArray(int n)
{
     int *a;

     a = malloc(sizeof(int) * n);

     if(a == 0) abort();                 /* die on failure */

     return a;
}

However, if you aren't required to use malloc, then create an int, pass the address of the int, and change it directly in the function like this:

#include <stdio.h>
#include <stdlib.h>

void doStuff();

void doStuff(int *a){
    *a = 3;
    printf("%d \n", *a);
};

int main(){
    int a;

    doStuff(&a);
    printf("%d", a);
}
m-atoms
  • 61
  • 1
  • 5
0

here there are two a's.both are pointers .one belongs to main() and other to dostuff(). when you are passing a from main() a's value which is uninitialized is passed on dostuff's a.later when you malloc dostuff a gets a new address and value is updated at the new address.however main() a value is still uninitialized.to solve the problem do malloc in the main function.or return a from dostuff and update it in main().

#include <stdio.h>
#include <stdlib.h>

int *doStuff();

int *doStuff(int *a){

a = malloc(sizeof(int));
*a = 3;
printf("%d \n", *a);
return a;
};


int main(){
    int* a;

    a=doStuff(a);
    printf("%d", *a);

    free(a);
}
moon shines
  • 88
  • 10
0

The a variable in doStuff() is local to that function, its argument, it is not the same object as the a in main(). Passing the value of the a variable in main() has undefined behavior because that a is uninitialized in main().

To get correct behavior, change doStuff() to take no arguments and return an int*:

#include <stdio.h>
#include <stdlib.h>

int *doStuff(void);

int *doStuff(void) {
    int *a = malloc(sizeof(int));
    if (a != NULL) {
        *a = 3;
        printf("in doStuff: %d\n", *a);
    }
    return a;
}

int main() {
    int *a;

    a = doStuff();
    if (a != NULL) {
        printf("in main: %d\n", *a);
        free(a);
    } else {
        printf("doStuff returned a NULL pointer\n");
    }
    return 0;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • Thank your very much!! that works 2 yes! But I had to relate on a problem where I got a complete doStuff.h file :) This was just an example for my problem. Editing the function-return-type is in my case not allowed :) – Newwboi May 18 '20 at 08:55
0

If you desperately need to use malloc() within doStuff() and retain the allocated address for the parameter passed to the function, you need to pass a pointer to an integer pointer as opposed to an integer pointer.

The modified code below uses a **int instead of *int, so that the modifications made to your *int variable is retained outside of if doStuff(). I used extra parentheses around **int for expressiveness, you can omit them.

#include <stdio.h>
#include <stdlib.h>

void doStuff();

void doStuff(int **a) {
    *a = malloc(sizeof(int));
    *(*a) = 3;
    printf("%d \n", *(*a));
};

int main() {
    int *a;

    doStuff(&a);
    printf("%d\n", *a);

    free(a);
    return 0;       /* explicit return from main */
}
fnisi
  • 1,181
  • 1
  • 14
  • 24
  • 1
    Thank your very much!! But I didn't want to use global variables or a pointer to pointer. The answere of m-atoms helped me :) – Newwboi May 18 '20 at 08:52