简体   繁体   中英

allocating in heap memory array of pointers to struct

I'm trying to make simple data base by using structure like

struct Employee{
    char* name;
    int ID;
    int GPA;
    int salary;
};

i know how i can allocate one pointer of the struct type in heap by using that

struct Employee* emp=malloc(sizeof(Employee));

my problem now that i'm not very good in allocating processes and i want to allocate N number of pointer of the struct in the heap and i can't use arrays because the size will not be knows until running time any suggestions ?

Yes, you need to allocate the memory dynamically, ie allocate a new heap block for every new struct Employee .

You can do this for example using realloc when the size changes:

yourArrayPtr=realloc(yourArrayPtr,newsize * sizeof(struct Employee));

The realloc function basically assigns a new amount of memory for the data pointed by its return value. It is a convenient way of expanding, or shrinking a dynamically allocated array. newsize here is the new number of elements of your array, and it is multiplied by the size of one Employee structure, rendering the total amount of space needed for your new array. The return value of realloc is assigned to your array pointer, so that it points specifically to this newly allocated space. In this case it could be used like this:

struct Employee* emp= NULL;

And then when you need it:

int n = 8;
emp = realloc (emp, n * sizeof(struct Employee));

Keep in mind, that you still have to free this memory.

You can now initialize and access this data:

emp[3] = {value1, value2, value3, ...};

As far as structures go, you could also think of another data structure - a linked list, where every structure contains a pointer to its successor. You can read about it here: http://www.cprogramming.com/tutorial/c/lesson15.html

In your case, it would be sth like:

struct Employee{
    char* data;
    struct Employee* next;
};

As others mentioned, you can use malloc to create as many entries of employee details in heap and store them in a dynamic list( linked list ). i have given an example code, you can start from here and extend it, if you want to save the employee details before exiting, you can write it to a binary file and read it back when you run the program again(based on your needs), since once you program exits all the data will be lost.

#include <stdio.h>
#include <stdlib.h>
// Max length for employee name
const unsigned int MAX_NAME_LEN = 100;

typedef struct Employee{
    char* name;
    unsigned int ID;
    int GPA;
    float salary;
} EMPLOYEE ;


typedef struct emp_database_entry {
    EMPLOYEE data;
    struct emp_database_entry *next;
} EMPLOYEE_ENTRY;

typedef EMPLOYEE_ENTRY* EMPLOYEE_DATABASE;

// to create a new employee
EMPLOYEE_ENTRY* createEmployee() {

    EMPLOYEE_ENTRY *newEmp = (EMPLOYEE_ENTRY*)malloc(sizeof(EMPLOYEE_ENTRY));
    printf("Enter Employee Name:");
    newEmp->data.name = (char*)malloc( MAX_NAME_LEN * sizeof(char) );
    scanf("%s",newEmp->data.name);
    printf("Enter employee ID:");
    scanf("%u",&newEmp->data.ID);
    printf("Enter employee GPA:");
    scanf("%u",&newEmp->data.GPA);
    printf("Enter employee salary:");
    scanf("%f",&newEmp->data.salary);
    newEmp->next = 0;

    return (newEmp);
}

// add a new employee to database
EMPLOYEE_DATABASE addEmployee(EMPLOYEE_DATABASE db) {

    EMPLOYEE_ENTRY *newEmp = createEmployee();
    if(db == NULL) {
        // add the first entry
        db = newEmp;
    } else {
        // add it to the top
        newEmp->next = db;
        db = newEmp;
    }
    return (db);
}
// Search for Employee using ID
EMPLOYEE_ENTRY* searchEmployee(EMPLOYEE_DATABASE db, unsigned int ID) {
    EMPLOYEE_ENTRY *employee = db;
    if(employee == NULL) {
        printf("There are no Employees in the database\n");
        return (NULL);
    }
    // Search till the end, if a match is found return the
    // pointer to employee
    while( employee != NULL ) {
        if( employee->data.ID == ID )
            return (employee);
        else
            employee = employee->next;
    }
    return (NULL);
}

void printOneEmployee( EMPLOYEE_ENTRY *employee ) {
    printf("Employee Details\n");
    printf("Name  : %s\n",employee->data.name);
    printf("ID    : %u\n",employee->data.ID);
    printf("GPA   : %d\n",employee->data.GPA);
    printf("Salary: %f\n\n",employee->data.salary);
}
// Print all employee details
void printAllEmployee( EMPLOYEE_DATABASE db ) {
    EMPLOYEE_ENTRY *employee = db;
    // traverse till the end and print one by one
    while( employee != NULL ) {
        printOneEmployee(employee);
        employee = employee->next;
    }
}
// freeing allocated memory
void freeDatabase(EMPLOYEE_DATABASE db) {
    EMPLOYEE_DATABASE employee = 0;
    while( db != NULL ) {
        employee = db;
        db = employee->next;
        free(employee->data.name);
        free(employee);
    }
}

void displayOption( EMPLOYEE_DATABASE db ) {

    int option = -1;

    while( option != 5 ) {
        printf("\nEmployee DataBase\n");
        printf("1: Add a Employee\n");
        printf("2: Search Employee\n");
        printf("3: Print All Employee\n");
        printf("4: Exit\n");
        printf("Enter a number for the choice: ");
        scanf("%d",&option);

        if( option > 4 || option < 0 ) {
            option = -1;
        }

        switch( option ) {
            case 1:
                db = addEmployee(db);
                break;
            case 2:
                int ID;
                if(db != NULL){
                   printf("Enter the Employee ID: ");
                   scanf("%d",&ID);
                   printf("Search Result1: ");
                   printOneEmployee(searchEmployee(db, ID));
                }
                else
                    printf("No Employees in the database\n");
                break;
            case 3:
                printAllEmployee(db);
                break;
            case 4:
                freeDatabase(db);
                printf("DataBase Deleted\nExiting..");
                exit(0);
            default:
                printf("Invalid Option!. Try Again!.\n");

        }
    }
}
int main() {

    EMPLOYEE_DATABASE db = 0;
    displayOption(db);

    return (0);
}

Of course you can use arrays if you use C99. In C99 you can do things like:

scanf("%d", &N);
struct Employee emp[N];
emp[0].ID = 123;

if you are using gcc (or MinGW), just be sure to compile with -std=c99

On the other hand, if you just want to create an array on the heap, you can do something like:

scanf("%d", &N);
struct Employee* emp=malloc(N*sizeof(Employee));
emp[0].ID =123;
...
// do not forget to deallocate emp
free(emp);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM