Привет,
Я немного плохо знаком с функцией 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;
}
Да! 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;
}
Сама память сохраняется, но происходит утечка, потому что вы не предоставляете выделенный указатель для вызывающей стороны. Кроме того, вы печатаете 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;
}
Адрес int * b
удаляется при возврате функции. Чтобы сохранить его, вам нужно использовать указатель на указатель
int f1(int ** b) {
*b = malloc(sizeof(int));
**b = 5;
}
Похоже, вы неправильно понимаете фундаментальную часть того, как работает 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 ()
была изменена, чтобы печатать указанное значение, а не сам указатель.
На самом деле ваша проблема связана не с malloc, а с тем фактом, что вы передаете значение, которое в настоящее время содержит указатель, а не его адрес. Попробуйте сделать следующее:
int f1(int ** b) {
*b = malloc(sizeof(int));
**b = 5;
}
int main() {
int * a;
f1(&a);
printf("%d\n", *a);
return 0;
}
При передаче значения указателя в том виде, в каком вы были, созданное значение malloc не могло быть сохранено в указателе.
Предположим, вы присваиваете значение NULL
элементу a перед вызовом функции f1
. Теперь, когда функция f1 определена, она принимает свой аргумент (указатель на int
) по значению. То есть b
будет другой переменной типа int *
, которая будет копией a
. Таким образом, b
тоже будет иметь значение NULL
. Теперь в f1
вы изменяете значение на b
, присваивая ему адрес памяти, выделенной динамически с помощью malloc
. Предположим, что адрес памяти - 0x123
. В результате этого присвоения b
изменил свое значение с NULL
на 0x123
, но a
(в main
) продолжает хранить 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;
}