Почему я получаю эту ошибку?
Вы перезаписываете указатель destination
вместо присвоения значения, возвращаемого malloc
указателю , на который указывает указатель destination
.
- Вместо
*destination = (int*)malloc(sizeof(int) * 10)
вы должны набрать **destination = malloc(sizeof(int) * 10)
. - Вместо
*destination[i] = i
вы должны набрать (**destination)[i] = i
.
In C оператор индекса массива []
имеет более высокий приоритет, чем оператор косвенного обращения *
. Кроме того, первый ассоциативен слева направо , а второй ассоциативно справа налево .
В вашем случае это означает, что вам нужно набрать (**destination)[i] = i;
вместо **destination[i] = i
, потому что в противном случае [i]
будет оцениваться до **
, и вы в конечном итоге будете использовать wild-указатель (что приведет к очень вероятной ошибке сегментации в общем и совершенно точно в этом случае, поскольку вы ссылаетесь на нулевой указатель, когда i == 0
).
Как это можно исправить?
Исправление «просто заставь это работать» - это то, что я представил выше.
Однако это не решает фундаментальную проблему с вашим кодом, которая заключается в том, что излишне сложно . Использование указателя на указатель очень подвержено ошибкам и его следует избегать. Действительно, в этом случае вообще нет необходимости использовать его.
Следующее делает именно то, что вы хотите, без всякой ненужной сложности:
int* func_1()
{
int* destination = malloc(sizeof(int) * 10);
for (int i = 0; i < 10; ++i)
{
destination[i] = i;
}
return destination;
}
int main()
{
int* pointer = func_1();
free(pointer);
return 0;
}
Обратите внимание, что я sh сохраню значения, которые я присвоил динамически распределенной памяти внутри функции, после выхода из функции, и это причина, по которой я передал адрес указателя, на который я хочу динамически распределять память.
Как я продемонстрировал выше, нет причин передавать указатель на указатель на функцию. Память, выделенная с помощью malloc
, остается для вас навсегда, вам просто нужно отследить ее и освободить с помощью вызова free
, когда он вам больше не нужен. То, как вы отслеживаете память, не имеет значения - в этом случае достаточно просто вернуть указатель. Изменение pointer
внутри func_1
вместо перехвата возвращаемого значения функции не дает никаких дополнительных преимуществ и служит только для того, чтобы сделать код более сложным, чем нужно.
У меня сложилось впечатление, что вы несколько смущен насчет указателей, поэтому я рекомендую вам пересмотреть тему. Вот довольно четкое объяснение относительно указателей, которое также охватывает указатели на указатели (и указатели на указатели на указатели): Как работают указатели в C?
Подробнее: