Как обращаться к ячейкам динамического массива, переданного в функцию? - C (СИ)
Формулировка задачи:
Попытки присвоить значение или вывести на печать содержимое ячейки динамического массива заканчиваются Segmentation fault. Как правильно обращаться к ячейкам динамического массива в строках 22 и 25 внутри функции?
// example.c
#include <stddef.h>
#include <stdlib.h>
void external_function(float **, size_t *);
int main(void){
float *dynamic_array;
size_t size_of_dynamic_array=0;
external_function(&dynamic_array,&size_of_dynamic_array);
free(dynamic_array);
return 0;
}// external_function.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void external_function(float **dynamic_array, size_t *size_of_dynamic_array){
// Тут производятся некие вычисления, в результате которых можно узнать, какого
// размера будет динамический массив. Допустим, результат равен десяти:
*size_of_dynamic_array=10;
// Выделение памяти
*dynamic_array = (float*) malloc(*size_of_dynamic_array * sizeof(float));
for(size_t m=0; m<*size_of_dynamic_array; ++m) {
// Попытки присвоить значение или вывести на печать содержимое ячейки динамического
// массива заканчиваются Segmentation fault
// Например, попытка заполнить ячейку динамического массива через fscanf() заканчивается
// Segmentation fault
if(!fscanf(ptrfile, "%f",&dynamic_array[m])) { ... }
// Или попытка вывести содержимое ячейки тоже заканчивается Segmentation fault
printf("dynamic_array[%zu]=%.2f\n",m,dynamic_array[m]);
}
}gcc -pipe -g -O0 -Wall -Wextra -Wpedantic -Werror -Wshadow -std=c11 -c example.c gcc -pipe -g -O0 -Wall -Wextra -Wpedantic -Werror -Wshadow -std=c11 -c external_function.c gcc example.o external_function.o -o example
Решение задачи: «Как обращаться к ячейкам динамического массива, переданного в функцию?»
textual
Листинг программы
main() {
int *a, size;
f(&a, &size);
....
}
void f (int **pa, int *size)
{
int *ax = *pa; // Начиная с этого места *a === *ax. Обе эти переменные (a и ax) - есть один
//четырехбайтовый кусок памяти. Все, что вы ни сделаете с ax - вы делаете и с a
ax = malloc... // a в main получит то же значение - указатель на выделенную память в куче
ax = realloc(ax, newsize); // майновское a получило новое значение, указатель на новый кусок
free(ax); // Кусок отдан на растерзание другим, но ax (и a!) на него по прежнему указывают, т.е. - в никуда.
// Пользоваться ими ни в функции, ни в майне нельзя
}
Объяснение кода листинга программы
- В функции main() объявлены две переменные: a и size. Переменная a является указателем на int, а переменная size - на int.
- В функции main() вызывается функция f(), передавая ей в качестве аргументов указатель на переменную a и указатель на переменную size.
- В функции f() происходит следующее:
- Объявляется переменная ax, которая является указателем на int и инициализируется значением переменной a.
- Значение переменной ax изменяется на результат вызова функции malloc().
- Значение переменной ax изменяется на результат вызова функции realloc().
- Вызывается функция free(), передавая ей в качестве аргумента переменную ax.
- После вызова функции free() значение переменной ax (и переменной a в функции main()) не меняется, поскольку они оба указывают на ту же область памяти.
- В конце функции main() есть пропущенное место, которое обозначено троеточием (...). Здесь могут находиться другие действия, которые не были указаны в вопросе.