Ответ 1
Причиной этой ошибки является то, что data
, используемый функцией create_array
, является локальной переменной, которая существует только внутри этой функции. Назначенный адрес памяти, полученный из malloc
, сохраняется только в этой локальной переменной и никогда не возвращается вызывающему.
Рассмотрим этот простой пример:
void func (int x)
{
x = 1;
printf("%d", x);
}
...
int a;
func(a);
printf("%d", a); // bad, undefined behavior - the program might crash or print garbage
Здесь копия переменной a
хранится локально внутри функции в качестве параметра x
. Это называется передачей по значению.
При изменении x
изменяется только локальная переменная. Переменная a
в вызывающем абоненте остается неизменной, и поскольку a
не инициализируется, она будет содержать "мусор" и не может быть надежно использована.
Указатели не являются исключением из этого правила передачи по значению. В вашем примере переменная указателя data
передается по значению функции. Указатель data
внутри функции является локальной копией, а назначенный адрес из malloc
никогда не передается вызывающему абоненту.
Таким образом, переменная указателя в вызывающем объекте остается неинициализированной, и поэтому программа вылетает из строя. Кроме того, функция create_array
также создала утечку памяти, так как после выполнения этой функции в программе больше нет указателя, отслеживающего этот фрагмент выделенной памяти.
Существует два способа изменить функцию для работы, как ожидалось. Либо вернув копию локальной переменной обратно вызывающему абоненту:
int* create_array (int size)
{
int* data = malloc(sizeof(*data) * size);
for(int i=0; i<size; i++)
{
data[i] = i;
}
print_array(data, size);
return data;
}
int main (void)
{
int* data;
const int size = 5;
data = create_array(size);
print_array(data, size);
}
или путем передачи адреса указателю указателя вызывающего абонента и записи непосредственно в переменную вызывающего:
void create_array (int** data, int size)
{
int* tmp = malloc(sizeof(*tmp) * size);
for(int i=0; i<size; i++)
{
tmp[i] = i;
}
*data = tmp;
print_array(*data, size);
}
int main (void)
{
int* data;
const int size = 5;
create_array(&data, size);
print_array(data, size);
}
Любая форма в порядке.