0

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 ?

trincot
357k38 gold badges282 silver badges338 bronze badges
asked Feb 15, 2015 at 15:19
3
  • Do you know the number of employees at initial allocation time, or can more employees be added over time? Commented Feb 15, 2015 at 15:24
  • once the user enters number of size it is the number of employees. Commented Feb 15, 2015 at 15:28
  • Don't forget name is also a pointer and you may need to allocate (and free) space for it. Commented Feb 15, 2015 at 15:43

3 Answers 3

1

Yes, you need to allocate the memory dynamically, i.e. 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;
};
answered Feb 15, 2015 at 15:22
Sign up to request clarification or add additional context in comments.

3 Comments

i didn't use realloc before just i used malloc so can you please expand more ?
now emp points to the 8 blocks of heap ? and how i can access every block of them ?
realloc can return NULL. You should use a different pointer for the returned value and if it is not NULL, assign the returned value to the pointer that is actually used.
1

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);
}
answered Feb 15, 2015 at 21:18

Comments

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

4 Comments

am using minGW compiler and i would try your second code but i have question struct Employee* emp=malloc(N*sizeof(Employee)); how i can deal with that deceleration as it array ?
also emp supposed to be pointer must i use x-<y syntax instead of x.y ?
In case the size of the array should decrease after created, then you can use realloc() as Michał Szydłowski suggested.
Yes, a typo. Corrected.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.