malloc and free with a dynamically changing structure

a 夏天 提交于 2020-01-07 02:25:28

问题


I am having trouble with moving my pointer in a dynamically changing structure. I have created my code where you can malloc more memory and this seems to be working. The problems that I am running into is how to add to the structure, how to free memory and how to move from structure to structure and print all items.

I am trying to test add and print (the delete function that is there does not seem to work, segfaults)

When I add to the struct and then print the struct I get a segfault from the values that I have added. I don't know if I am moving from the first struct to the next struct correctly.

#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));


}

回答1:


First problem: Ok... you didn't include the declaration of employee type. I guess first and last are declared as char pointers, and this is an error. You need them to be fixed size char array or this will never work. Choose a maximum length for the string and declare the structure like this.

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

Previous post:

Well i must admit i don't like much this way of implementing the thing. I would use a more stable approach.

First of all, since it is just a list of items, you can use a doubly linked list. This will allow you to add and remove elements with an O(1) complexity. Quite good, indeed.

This will also allow you to iterate all items from the first to the last.

For doing that i would use a more OOP oriented approach :) I know, we are in C but listen to this idea.

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);
}

Now, to iterate all items is simple:

Employee* current;
for (current = list->First; current != null; current = current->Next)
    printf("%s %d\n", current->name, current->age);



回答2:


You're not using malloc to allocate first, last, and start_date attributes of employee. Therefore, when you call free on the pointers in deleteData, you're corrupting memory. I would also consider using a linked list or some other data structure (like an array) to hold the employee records instead, allowing you to have a cleaner interface.



来源:https://stackoverflow.com/questions/7856749/malloc-and-free-with-a-dynamically-changing-structure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!