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

Привет,

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

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

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

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

13
задан Antti Haapala 12 May 2019 в 10:32
поделиться

6 ответов

Да! a равно , переданному по значению , поэтому указатель b в функции f1 будет локальным .. либо return ] 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;
}
26
ответ дан 1 December 2019 в 17:51
поделиться

Сама память сохраняется, но происходит утечка, потому что вы не предоставляете выделенный указатель для вызывающей стороны. Кроме того, вы печатаете 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;
}
6
ответ дан 1 December 2019 в 17:51
поделиться

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

int f1(int ** b) {
   *b = malloc(sizeof(int));
   **b = 5;
}
0
ответ дан 1 December 2019 в 17:51
поделиться

Похоже, вы неправильно понимаете фундаментальную часть того, как работает 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 - важно, если вы хотите, чтобы он был «заполнен». in 'by f1 () , так сказать. Наконец, функция printf () в main () была изменена, чтобы печатать указанное значение, а не сам указатель.

9
ответ дан 1 December 2019 в 17:51
поделиться

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

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

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

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

0
ответ дан 1 December 2019 в 17:51
поделиться

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

Есть два способа решить эту проблему. Во-первых, можно заставить функцию f1 вернуть значение измененной b и затем присвоить его обратно a в main, а во-вторых, можно передать a по адресу, так что любые изменения, сделанные в f1, повлияют и на a в 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;
}
5
ответ дан 1 December 2019 в 17:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: