1

I am trying to create a structure that can be dynamically added to with malloc and free. There are three functions that I need to implement. I need to be able to print the current structure and move to the next structure and print it as well (Needs to loop through and print each struct).

This part give me an error that goes as follow:

No more issues occured look at what I edited. I cannot submit my own answers

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

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

Here's some of my source:

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

These are two of the three functions that I have implemented.

This is the header file that is included:

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

Can anyone help point out what is causing the error or what it means when you have a pointer without cast and how to go about making line 32 a compatible pointer type.

Solution: In the createRecord function is deleted the "[MAXSIZE]" and the code ran with no issues

jenglee
  • 343
  • 2
  • 5
  • 10

3 Answers3

1

The function definition doesn't match the return statement:

// 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;
}
Brendan Long
  • 53,280
  • 21
  • 146
  • 188
  • changed myEmployee **createRecord to myEmployee *createRecord. Still having issues with line 27 and 29 – jenglee Oct 12 '11 at 01:41
1

Structures with variable-sized data inside can be tricky. There are two primary tricks; one is to place your variable-length data as the very last member of the struct, and account for its space when you allocate your structures. This works for exactly one variable-length data element. (Well, you can do more complicated tricks, but it surely isn't worth it most of the time.)

In your case, your structures are actually a fixed size -- which is a good thing -- but it does mean that you also have to allocate memory separately for your char pointers:

myEmployee **createRecord(char *fullname, char *date, float sal)
{
    myEmployee *newEmployees = malloc(sizeof(myEmployee));
    if (newEmployees != NULL) {
        newEmployees->fullName[MAXSIZE] = fullname;

Your ->fullName pointer is garbage at this point. I don't know what it points to, but MAXSIZE bytes after, it attempts to store a single character. (Which is where your type error comes from -- but fixing it takes much more work than you might guess.)

Who is in charge of the char *fullname that you have passed into this function? Is it a long-lived piece of memory that you have malloc(3)ed elsewhere? Or was it a stack-allocated variable in whatever function called createRecord()?

If the variable was stack-allocated (or otherwise intended for a short lifespan), then you need to allocate a place to store a copy:

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;

If the variable was allocated with malloc(3) (or otherwise intended for a long lifespan), then you can simply update pointers:

myEmployee **createRecord(char *fullname, char *date, float sal)
{
    myEmployee *newEmployees = calloc(1, sizeof(myEmployee));
    if (newEmployees != NULL) {
        newEmployees->fullName = fullname;

So the right answer depends upon how you wish to approach the long-term storage of your objects. Which functions are in charge of allocating and de-allocating the members of your functions? I strongly recommend the first approach -- that way, you can write the allocation routine here and the de-allocation routine in destroyRecord() (or whatever the paired function is) and be certain you do not have memory leaks.

sarnold
  • 102,305
  • 22
  • 181
  • 238
  • I would use strdup() for fullname + startdate and calloc() for the struct itself. – ott-- Oct 12 '11 at 01:49
  • @ott--: `strdup(3)` in place of `strlen(3)`, `malloc(3)`, `strcpy(3)` is an excellent idea (especially since that `+ 1` would be easy to forget). I was on the fence about `calloc(3)`, but it can definitely catch bugs if the structure changes, and heck, all the memory will be in the CPU cache _anyway_, so double-updating can't add _that_ much of a speed penalty. Good catches, both. Thanks! – sarnold Oct 12 '11 at 02:01
0
1: myEmployee  employee;
2: &employee.fullName;
3: &employee.startdate;
Slrs
  • 105
  • 1
  • 3
  • 11