malloc и свободный с динамически изменяющейся структурой - PullRequest
0 голосов
/ 22 октября 2011

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

Я пытаюсь проверить добавление и печать (функция удаления, которая там находится, похоже, не работает, segfaults)

Когда я добавляю в структуру и затем печатаю структуру, я получаю ошибку сегментаиз значений, которые я добавил.Я не знаю, правильно ли я перехожу из первой структуры в следующую.

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

/********************************************
Creates more memory for size (strut * rec+1)
*********************************************/

employee *create(int record){
employee *new_employee = malloc(sizeof(employee) * (record+1));

return new_employee;    
}

/********************************************
Copies the data from one structure to a new structure with 
size "structure" multipled by rec+1
***********************************************/
employee *copy(employee *data, int record){
    employee *new_employee = create(record);
int i;
    for(i = 0; i<record;i++){
        new_employee->first = data->first;
        new_employee->last = data->last;
        new_employee->start_date = data->start_date;
        new_employee->sal = data->sal;
        data++;
    }
    /********************
    Needs to free the old struct
    *********************/
    //deleteData(data, record);

return new_employee;
}
/********************************************
Function prints everything in the struct
*********************************************/
void printStruct(employee *data, int record){
int i;

    for(i = 0; i<record; i++){
        printf("\nEntry: %d\n", i+1);           
        printf("The employee's name is %s %s\n", data->first, data->last);
        printf("The employee was hired on: %s\n", data->start_date);
        printf("The employee make $%f\n\n", data->sal); 
        data++;     
    }
}
/******************************************
Function frees the old data base
*******************************************/
void deleteData(employee *data, int record){
int i;
    for(i = 0; i<record; i++){
        free(data->first);
        free(data->last);
        free(data->start_date);
        data++;
    }
    free(data);
}
/******************************************
Adds an employee to the new structure
*******************************************/
employee *add(employee *data,char *fname, char *lname, char *date, float salary, int record){
employee *employeeDB = create(record);
employeeDB = copy(data, record);
int i;
    employeeDB++;
    employeeDB->first = fname;
    employeeDB->last = lname;
    employeeDB->start_date = date;
    employeeDB->sal = salary;

return employeeDB;
}




/**************************
Starts of the main function
***************************/

int main(void){
    //Keeps track of the number of records that are in the structure
int rec = 0;
    //Keeps the number of accesses to the structure. Even with the one entry   the structure has not been accessed. 
int acc = 0;
    //Holds the input information for the menu
int input;
    //holds the information for inputing user first name
char *fname;
    //holds the information for inputing user last name
char *lname;
    //holds the information for for the startdate
char *start;
    //holds the information for the salary;
float sal;
/*********************************
This next section adds an employee to the record

************************************/
//This creates the first entry to the dynamic structure.
employee *first_employee = create(rec);
first_employee->first = "FIRST";
first_employee->last = "LAST";
first_employee->start_date = "June-20th-2006";
first_employee->sal = 55555.55;
//increase the number of records    
rec = rec+1;

employee *new_employeeDB = add(first_employee, "fname", "lname", "JUNE-20th-2010", 55555.55, rec);
rec = rec + 1;
printStruct(new_employeeDB, rec);


printf("%d\n", (sizeof(employee)* rec));


}

Ответы [ 2 ]

0 голосов
/ 22 октября 2011

Первая проблема: хорошо ... вы не включили объявление типа сотрудника. Я думаю, что первый и последний объявлены как указатели на символы, и это ошибка. Вам нужно, чтобы они были массивом символов фиксированного размера, иначе это никогда не сработает. Выберите максимальную длину строки и объявите структуру следующим образом.

typedef struct
{
    char name[50];
    char surname[50];
    ....
} employee;

Предыдущее сообщение:

Ну, я должен признать, что мне не очень нравится этот способ реализации вещи. Я бы использовал более стабильный подход.

Прежде всего, поскольку это просто список элементов, вы можете использовать двусвязный список. Это позволит вам добавлять и удалять элементы со сложностью O (1). Действительно хорошо.

Это также позволит вам перебирать все элементы от первого до последнего.

Для этого я бы использовал более ООП-ориентированный подход :) Я знаю, мы находимся в C, но слушаем эту идею.

typedef struct
{
    MyList* OwnerList;
    Employee* Previous;
    Employee* Next;

    char name[50];
    int age;
} Employee;

typedef struct
{
    Employee* First;
    Employee* Last;
    int Count;
} MyList;

MyList* AllocList() { return calloc(sizeof(MyList), 1); }

void DeleteList(MyList* list)
{
    Employee* current;
    Employee* next;
    for (current = list->First; current != NULL; current = next)
    {
        next = current->Next;
        free(current);
    }
    free(list);
}

int GetCount(const MyList* list)
{
    return list->Count;
}

Employee* AddAmployee(MyList* list)
{
    Employee* result = calloc(sizeof(Employee), 1);
    Employee* last = list->Last;
    if (last != null)
        last->Next = result;
    else
        list->First = result;
    result->Previous = last;
    list->Last = result;
    ++list->Count;
    result->OwnerList = list;
    return result;
}

void RemoveEmployee(Employee* employee)
{
    /* i leave removal for you as exercise :) look for doubly linked list */
    free(employee);
}

Теперь перебрать все элементы просто:

Employee* current;
for (current = list->First; current != null; current = current->Next)
    printf("%s %d\n", current->name, current->age);
0 голосов
/ 22 октября 2011

Вы не используете malloc для выделения атрибутов first, last и start_date сотрудника. Поэтому, когда вы вызываете free для указателей в deleteData, вы повреждаете память. Я также хотел бы рассмотреть возможность использования связанного списка или некоторой другой структуры данных (например, массива) для хранения записей о сотрудниках, что позволит вам иметь более чистый интерфейс.

...