Почему мой динамически размещенный массив не доступен вне его функции? [С] - PullRequest
1 голос
/ 14 февраля 2020

Я пытаюсь получить доступ к array, созданному в функции fooA() в функции main. Я динамически выделяю array, используя malloc и указываю на него переданный указатель, но в основном указатель больше не указывает на то же значение.

int main() {
    int *test;
    fooA(test);
    printf("%d\n", test[0]);
    free(test);
}

void fooA(int *pass){
    int pass = malloc(5*sizeof(int));
    for(int i=0;i<5;i++){
        pass[i] = i;
    }
}

1 Ответ

3 голосов
/ 14 февраля 2020

Во-первых, проблемы в коде ....


void fooA(int *pass)  /*<<<<  pass is declared here */
{
    /* 
       however you have redefined pass as a different type here.
       This variable hides the previous definition of pass. 
       I'd suggest turning up the warning level on your compiler 
       to catch errors like this. (-Wall on gcc/clang, or warning 
       level 4 on Visual C)
     */
    int pass = malloc(5*sizeof(int));
    for(int i=0;i<5;i++){
        pass[i] = i;
    }
}

Позже, когда вы вызываете метод, вы передаете копию теста в fooA вместо ссылки на исходную переменную. т. е. любые изменения, внесенные вами в 'pass' внутри fooA, будут работать с копией, а не с исходной переменной.

    int *test;
    fooA(test);

Самый простой вариант здесь - просто вернуть указатель.

/* change the prototype to return the pointer instead of passing in as arg! */
int* fooA(void);

int main() {

    /* this should now be good */
    int *test = fooA();
    printf("%d\n", test[0]);
    free(test);
}

int* fooA(void){
    int* pass = malloc(5*sizeof(int));
    for(int i=0;i<5;i++){
        pass[i] = i;
    }
    return pass;
}

Если вы хотите сделать это с аргументом функции, это возможно, но только если вы используете указатель на указатель, т.е.

void fooA(int** pass);

int main() {
    int *test;
    fooA(&test); /*< passing address of test variable */
    printf("%d\n", test[0]);
    free(test);
}

void fooA(int** pass) {
    /* need to dereference pass here to modify the original pointer value */
    *pass = malloc(5*sizeof(int));
    for(int i=0;i<5;i++){
        (*pass)[i] = i;
    }
}

Хотя этот вопрос помечен как C, для полноты, в C ++ вы можете передать переменную по ссылке (т.е. добавить символ & в конец типа)

void fooA(int*& pass) {
    // working on the original variable, rather than a copy. 
    pass = (int*)malloc(5*sizeof(int));
    for(int i=0;i<5;i++){
        pass[i] = i;
    }
}

И теперь этот код будет работать просто отлично:

    int *test;
    fooA(test);
...