Структуры с данными переменного размера могут быть сложными. Есть два основных трюка; один из них - поместить данные переменной длины в качестве самого последнего члена из struct
и учитывать их пространство при выделении структур. Это работает точно для одного элемента данных переменной длины. (Ну, вы можете делать более сложные трюки, но это, безусловно, не стоит в большинстве случаев.)
В вашем случае ваши структуры на самом деле имеют фиксированный размер - что хорошо, но это означает, что вам также нужно выделять память отдельно для указателей на символы:
myEmployee **createRecord(char *fullname, char *date, float sal)
{
myEmployee *newEmployees = malloc(sizeof(myEmployee));
if (newEmployees != NULL) {
newEmployees->fullName[MAXSIZE] = fullname;
Ваш указатель ->fullName
на данный момент является мусором. Я не знаю, на что он указывает, но MAXSIZE
байт после, он пытается сохранить один символ. (Отсюда и ваша ошибка типа - но ее исправление требует гораздо больше работы, чем вы можете догадаться.)
Кто отвечает за char *fullname
, который вы передали в эту функцию? Это долгоживущий кусок памяти, который у вас есть в другом месте? Или это переменная, выделенная в стеке, в любой функции, называемой createRecord()
?
Если переменная была выделена в стеке (или иным образом предназначена для короткого срока службы), то вам нужно выделить место для хранения копии:
myEmployee **createRecord(char *fullname, char *date, float sal)
{
myEmployee *newEmployees = calloc(1, sizeof(myEmployee));
if (newEmployees != NULL) {
newEmployees->fullName = strdup(fullname);
/* handle failure how you wish */
if (!newEmployees->fullName)
goto fail;
Если переменная была выделена с помощью malloc(3)
(или иным образом предназначена для длительного срока службы), то вы можете просто обновить указатели:
myEmployee **createRecord(char *fullname, char *date, float sal)
{
myEmployee *newEmployees = calloc(1, sizeof(myEmployee));
if (newEmployees != NULL) {
newEmployees->fullName = fullname;
Таким образом, правильный ответ зависит от того, как вы хотите подходить к долгосрочному хранению ваших объектов. Какие функции отвечают за распределение и отмену распределения членов ваших функций? Я настоятельно рекомендую первый подход - таким образом, вы можете написать здесь подпрограмму выделения и подпрограмму отмены выделения в destroyRecord()
(или какой-либо другой парной функции) и быть уверенным, что у вас нет утечек памяти.