Как обращаться к ячейкам динамического массива, переданного в функцию? - 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() есть пропущенное место, которое обозначено троеточием (...). Здесь могут находиться другие действия, которые не были указаны в вопросе.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д