employee **array;
НЕ является массивом, это одиночный указатель.( указатель на указатель на сотрудника ).
Какое значение size
при вызове:
for (int i = 0; i < size; i++)
size
является неопределенным (его значениекакое бы значение мусора ни находилось в памяти при запуске программы).Вы вызываете неопределенное поведение , пытаясь получить доступ к неопределенному значению.size
должен быть установлен перед использованием (одинаково для всех переменных)
В этой же точке array
является неинициализированным указателем , пытающимся получить доступнеопределенный адрес так же плохо.(Помните, что указатель - это просто нормальная переменная, которая содержит адрес чего-то еще в качестве значения).Поскольку адрес, хранящийся в array
, еще не был назначен, и для какой-либо структуры employee
не было выделено ни одного хранилища, вы не можете выполнить:
fscanf(fptr, "%d,%d,%f", array[i]->tax, array[i]->savings, array[i]->salary);
Прежде чем использовать array
, вы должны:
- выделяет некоторое количество указателей и назначает начало блока памяти, содержащего выделенные указатели,
array
, а затем - выделяет память для каждой вашей структуры и назначает начальный адресдля каждого блока хранения, содержащего структуру одного из указателей
array[i]
.
Например, чтобы первоначально объявить 64 указателя, вы можете сделать:
array = malloc (64 * sizeof *array);
( примечание: использование указателя с разыменованным указателем (sizeof *array
) всегда приведет к правильному размеру шрифта, а не к попытке сопоставления с типом, например, sizeof (employee*)
)
ВСЕГДА проверяет каждое выделение, например
if (array == NULL) { /* if the pointer returned by malloc is NULL */
perror ("malloc-array"); /* issue diagnostic (perror is simple) */
exit (EXIT_FAILURE); /* handle error */
}
Теперь, как выделить для каждой структуры?(так же).Но подход, который намного легче читать, распределять и проверять, состоит в том, чтобы использовать временную структуру с автоматическим хранением и читать и заполнять временную структуру.Если чтение выполнено успешно, выделите место для вашей структуры, присвойте начальный адрес для этого блока памяти array[i]
, а затем присвойте содержимое временной структуры вашему новому блоку памяти.Например (после исправления size
initialization):
for (int i = 0; i < size; i++) {
employee tmp = { .tax = 0 }; /* declare temporary struct, initialized zero */
/* read values into temporary struct / VALIDATE every input */
if (fscanf (fptr, "%d,%d,%f", tmp.tax, tmp.savings, tmp.salary) == 3) {
array[i] = malloc (sizeof *array[i]); /* allocate for struct */
if (!array[i]) { /* validate allocation */
perror ("malloc-array[i]");
exit (EXIT_FAILURE);
}
array[i] = tmp; /* assign temp struct to allocated block */
}
}
Теперь, когда вы закончили с использованием вашего «массива», не забудьте освободить выделенную память.Например, предполагая, что вы правильно заполнили size
, вы можете сделать следующее:
for (int i = 0; i < size; i++)
free (array[i]); /* free each allocated struct */
free (array); /* free pointers */
Возможно, в вашем опубликованном коде есть дополнительные ошибки (в некотором беспорядочном порядке), но это наиболеенемедленные ошибки, с которыми вы сталкиваетесь.Внесите изменения и протестируйте дальше.Убедитесь, что все переменные правильно инициализированы перед их использованием.Убедитесь, что вы выделили хранилище для каждого указателя, который будете использовать, а затем выделите для каждой структуры назначьте адрес для хранения структуры одному из ваших выделенных указателей.Если вы столкнулись с другим блокпостом, либо отредактируйте этот вопрос (или, желательно, задайте новый вопрос), указав конкретную проблему, на которой вы застряли.