Создание динамически изменяющихся структур в C - PullRequest
1 голос
/ 12 октября 2011

Я пытаюсь создать структуру, которую можно динамически добавлять с помощью malloc и free.Есть три функции, которые мне нужно реализовать.Мне нужно иметь возможность распечатать текущую структуру и перейти к следующей структуре и распечатать ее (необходимо циклически просмотреть и распечатать каждую структуру).

Эта часть дает мне ошибку, которая выглядит следующим образом:

Больше не возникало проблем с просмотром того, что я редактировал.Я не могу представить свои собственные ответы

Employee.c:27: warning: assignment makes integer from pointer without a cast

Строка: printf(\n The Employee's name is:%s, employee->fullName);

Employee.c:29: warning: assignment makes integer from pointer without a cast
printf("\nThe Employee started on %s", employee->startdate);

Вот некоторые из моих источников:

#include <stdio.h>
#include <stdlib.h>
#include "Employee1.h"

/// PRINT RECORDS ///
void printRecords(myEmployee * emp)
{
    myEmployee *employee;
    for (employee = emp; employee != NULL; employee = employee->next) {

        printf("\nThe Employee's Name is: %s", employee->fullName);
        printf("\nThe Employee makes is a year $ %f", employee->salary);

        printf("\nThe Employee started on %s", employee->startdate);
        printf("\n\nThe Next Employee:\n");
    }

}

//// CREATERECORD ////
myEmployee *createRecord(char *fullname, char *date, float sal)
{
    myEmployee *newEmployees = malloc(sizeof(myEmployee));
    if (newEmployees != NULL) {
        newEmployees->fullName[MAXSIZE] = fullname;
        newEmployees->salary = sal;
        newEmployees->startdate[MAXSIZE] = date;
        newEmployees->next = NULL;
    }
    return newEmployees;
}

Это два из трехфункции, которые я реализовал.

Это заголовочный файл, который включен:

#include <string.h>
#define MAXSIZE 200

typedef struct employee {
    char *fullName;
    float salary;
    char *startdate;
    struct employee *next;

} myEmployee;

void printRecords(myEmployee * emp);
myEmployee *createRecord(char *fullname, char *date, float sal);
myEmployee *addRecord(char *fullname, char *date, float sal);
void deleteRecord();

Может кто-нибудь помочь указать, что является причиной ошибки или что это означает, когда у вас есть указатель безприведение и как сделать строку 32 совместимым типом указателя.

Решение: в функции createRecord удалено «[MAXSIZE]» и код запускается без проблем

Ответы [ 3 ]

1 голос
/ 12 октября 2011

Структуры с данными переменного размера могут быть сложными. Есть два основных трюка; один из них - поместить данные переменной длины в качестве самого последнего члена из 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() (или какой-либо другой парной функции) и быть уверенным, что у вас нет утечек памяти.

1 голос
/ 12 октября 2011

Определение функции не соответствует оператору возврата:

// This says it returns a myEmployee**
myEmployee **createRecord(char *fullname, char *date, float sal)
{
    myEmployee *newEmployees = malloc(sizeof(myEmployee));
    if (newEmployees != NULL) {
        newEmployees->fullName[MAXSIZE] = fullname;
        newEmployees->salary = sal;
        newEmployees->startdate[MAXSIZE] = date;
        newEmployees->next = NULL;
    }
    // This returns a myEmployee*
    return newEmployees;
}
0 голосов
/ 05 ноября 2011
1: myEmployee  employee;
2: &employee.fullName;
3: &employee.startdate;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...