-2

From https://cs50.stackexchange.com/questions/4671/memory-allocation-recommended-practices I read "you don't have to declare all your pointers, allocate memory for them and/or free the allocated memory in main". But I, unsuccessfully (execution returns Segmentation fault: 11), tried:

#include <stdio.h>
#include <stdlib.h>
void gener_random(int size, int *values) {
    values = malloc(size * sizeof(values));
    for(int i = 0; i < size; i++)
        values[i] = rand(); 
}
int main(int argc, char **argv) {
    int size = 10;
    int *values;
    gener_random(size, values);
    for(long i = 0; i < size; i++)
        printf(" %d", values[i]);
    return 0;
}

Instead, moving malloc inside main works:

void gener_random(int size, int *values) {
    for(int i = 0; i < size; i++)
        values[i] = rand(); 
}
int main(int argc, char **argv) {
    int size = 10;
    int *values;
    values = malloc(size * sizeof(values));
    gener_random(size, values);
    for(long i = 0; i < size; i++)
        printf(" %d", values[i]);
    return 0;
}

What's going on?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
KcFnMi
  • 5,516
  • 10
  • 62
  • 136
  • @StoryTeller There exists a canonical duplicate you can use for closing these, rather than using multiple links of diverse quality. C tag -> "About" to open [tag wiki](https://stackoverflow.com/tags/c/info), then scroll down to FAQ -> Dynamic memory allocation -> [Dynamic memory access only works inside function](https://stackoverflow.com/questions/39486797/dynamic-memory-access-only-works-inside-function). – Lundin Apr 24 '18 at 12:32
  • @Lundin - Fair point. Though you can edit the duplicate list, if you feel the canonical would suffice. That's how multiple dupes were racked up here. – StoryTeller - Unslander Monica Apr 24 '18 at 12:37
  • @StoryTeller Aye, just mentioning it here in case you or some other [tag:c] gold dupe hammer-wielder is not aware that we actually have a maintained FAQ with canonical dupes nowadays :) – Lundin Apr 24 '18 at 12:41
  • @Lundin - I was aware of it in the back of mind. Shame on me really, I recently chastised a user for not reading the tag wiki before posting. Thanks for making me follow my own advice, in a sense :) – StoryTeller - Unslander Monica Apr 24 '18 at 12:44

1 Answers1

2

You need to have a pointer to the malloc()ed area, you can mimic malloc()'s behavior like this

int *gener_random(int size) {
    int *values = malloc(size * sizeof(values));
    for(int i = 0; i < size; i++)
        values[i] = rand(); 
    return values;
}

The reason your code doesn't work is largely discussed on Stack Overflow, your int *value parameter is local to gener_random() and making it point to the return value of malloc() does not change your main()'s values, it does only make the local pointer point to new memory and you lose the reference when the function returns.

Two acceptable techniques exist,

  1. Return the locally declared pointer after you check that it was succesfuly allocated.

    int *gener_random(int size) {
        int *values = malloc(size * sizeof(values));
        if (values == NULL)
            return NULL;
        for(int i = 0; i < size; i++)
            values[i] = rand(); 
        return values;
    }
    
  2. Pass a pointer to the pointer itself and alter the variable in the function instead of the pointer value only.

    void gener_random(int size, int **values) {
        // Dereference the pointer to the pointer, to work
        // on the variable declared in `main()' (the original pointer)
        *values = malloc(size * sizeof(values));
        if (*values == NULL) // Perhaps reutnr `int' and error code
            return;
        for(int i = 0; i < size; i++)
            (*values)[i] = rand(); 
    }
    
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97