Память, выделенная с помощью malloc, не сохраняется вне области действия функции?

Привет,

Я немного новичок в функции malloc C, но из того, что я знаю, она должна хранить значение в куче, так что вы можете ссылаться на него с указателем из-за пределов исходной области видимости. Я создал тестовую программу, которая должна делать это, но я продолжаю получать значение 0 после запуска программы. Что я делаю неправильно?

int f1(int * b) {
 b = malloc(sizeof(int));
 *b = 5;
}

int main() {
 int * a;
 f1(a);
 printf("%d\n", a);
 return 0;
}

6 ответов

Да! a передается по значению, так что указатель b в функции f1 будет местный.. либо возврат b,

int *f1() {
    int * b = malloc(sizeof(int));
    *b = 5;
    return b;
}

int main() {
    int * a;
    a = f1();
    printf("%d\n", *a);
    // keep it clean : 
    free(a);
    return 0;
}

или пройти aадрес

int f1(int ** b) {
    *b = malloc(sizeof(int)); 
    **b = 5;
}

int main() {
    int * a;
    f1(&a);
    printf("%d\n", *a);
    // keep it clean : 
    free(a);
    return 0;
}

Похоже, вы неправильно понимаете основную часть работы C, а именно то, что это язык "передачи по значению". Для того чтобы main() Чтобы узнать о выделенной памяти, вы должны вернуть ее обратно. Следующий код сделает вам то, что вы хотите:

int f1(int **b)
{
    *b = malloc(sizeof(int));
    **b = 5;
}

int main(int argc, char **argv)
{
    int *a;
    f1(&a);
    printf("%d\n", *a);
    return 0;
}

Есть несколько различий между этим кодом и вашим; во-первых, подпись f1() изменилось, так что он может вернуть результат malloc() вызов в переданном указателе. Далее звонок f1() был изменен, чтобы передать адрес a скорее, чем a сам по себе - важно, если вы хотите, чтобы он был "заполнен" f1(), так сказать. Наконец, printf() в main() был изменен, чтобы печатать указанное значение, а не сам указатель.

Сама память сохраняется, но она протекает, потому что вы не предоставляете выделенный указатель вызывающей стороне. Кроме того, вы печатаете a когда вы должны печатать *a, Наконец, вы не возвращаете int из f1,

Пытаться:

void f1(int **b) {
 *b = malloc(sizeof(int));
 **b = 5;
}

int main() {
 int *a;
 f1(&a);
 printf("%d\n", *a);
 free(a);
 return 0;
}

Предположим, вы назначаете значение NULL перед вызовом функции f1, Теперь способ определения f1 принимает аргумент (указатель на int) по значению. То есть b будет другая переменная типа int * которая будет копией a, Так b тоже будет иметь значение NULL, Сейчас в f1 вы меняете значение на b присваивая ему адрес памяти, выделенный динамически, используя malloc, Допустим, что адрес памяти 0x123, В результате этого задания b изменил свое значение с NULL в 0x123 но amain) продолжает держать NULLпотому что изменение б не изменится a, поскольку они являются двумя отдельными переменными. В результате этого, когда вы возвращаетесь из функции f1 А останется без изменений.

Есть 2 способа решить эту проблему. Один, вы можете сделать функцию f1 вернуть значение измененного b а затем назначить его обратно в main и во-вторых, вы можете передать по адресу, так что любые изменения, сделанные в f1 повлияет на в main тоже.

// f1 now returns the value of b.
int* f1() {
 int *b = malloc(sizeof(int));
 *b = 5;
 return b;
}

int main() {
 int *a = NULL;
 a = f1(); // assign the return value of f1 to a.
 printf("%d\n", *a); // prints 5...not its *a not just a.
 return 0;
}

,

// f1 now takes the address of a. 
void f1(int **b) {
 *b = malloc(sizeof(int)); // you are actually altering a indirectly.
 **b = 5; 
}

int main() {
 int *a = NULL;
 f1(&a); // now pass the address of a to f1.
 printf("%d\n", *a); // prints 5...not its *a not just a.
 return 0;
}

Ваша проблема на самом деле не связана с malloc, а скорее с тем, что вы передаете значение, которое содержит указатель, а не его адрес. Попробуйте следующее:

int f1(int ** b) {
    *b = malloc(sizeof(int)); 
    **b = 5;
}

int main() {
    int * a;
    f1(&a);
    printf("%d\n", *a);
    return 0;
}

Передавая значение указателя, каким вы были, не было способа сохранить созданное значение malloc в указателе.

Адрес int *b удаляется при возврате функции. Чтобы сохранить его, вам нужно использовать указатель указателя

int f1(int ** b) {
   *b = malloc(sizeof(int));
   **b = 5;
}
Другие вопросы по тегам