ExperiencedSoup
ExperiencedSoup

Reputation: 97

I am making a code where we create humans, make them family and print their information but I can't print it

Basically, I made a structure which includes informations of a person. When I create them, I then hop into my other function which should print their information but I am stuck at that point.

This is my main where I call my functions:

int main() 
{
    Person* p1 = person_constructor("Steven", 1970, "male");
    display_person(p1);
    return 0;
}

This is where I construct my human, I am required to use dynamic memory allocation:

Person* person_constructor(char *name, int year_of_birth, char *sex)
{
    Person p = {};
    Person* pptr = &p;
    strcpy(p.name, name);
    p.year_of_birth = year_of_birth;
    strcpy(p.sex, sex);
    pptr = malloc(strlen(p.name) * sizeof(char) + strlen(p.sex) * sizeof(char) + sizeof(int));
    return pptr;
}

And this is the print function which can't print out the name:

void display_person(Person* p)
{
    printf("%s",p->name);
}

Upvotes: 0

Views: 67

Answers (4)

0___________
0___________

Reputation: 67820

Amended @Observer code to make it more safe, removing not needed code

#define some_value1 64
#define some_value2 64

typedef struct 
{
     char name[some_value1];
     char sex[some_value2];
     int  year_of_birth;
} Person;   

char *safe_strncpy(char *dest, const char *src, size_t length)
{
    strncpy(dest, src, length -1);
    dest[length - 1] = 0;
    return dest;
}

Person *person_constructor(const char *name, const int year_of_birth, const char *sex)
{
    Person *pptr;
    pptr=malloc(sizeof(*pptr));

    if(pptr)
    {
        safe_strncpy(pptr->name,name, sizeof(pptr->name));
        safe_strncpy(pptr->sex,sex, sizeof(pptr->sex));
        pptr->year_of_birth=year_of_birth;
    }

    return pptr;
}

Upvotes: 1

Gaurav
Gaurav

Reputation: 1600

Simplify it to:

//ASSUMING PERSON IS LIKE THIS:
typedef struct person
{
     char name[some_value1];
     char sex[some_value2];
     int  year_of_birth;
} Person;   


Person* person_constructor(char *name, int year_of_birth, char *sex)
{
    Person *pptr;
    pptr=malloc(sizeof(*pptr));

    memset(pptr->name,'\0',sizeof(pptr->name));
    memset(pptr->sex,'\0',sizeof(pptr->sex));

    strcpy(pptr->name,name);
    strcpy(pptr->sex,sex);
    pptr->year_of_birth=year_of_birth;

    return pptr;
}

Plus don't forget to check if space has been really allocated dynamically or not

Upvotes: 0

M Oehm
M Oehm

Reputation: 29126

Your constructor should allocate memory for the person object, then initialize the allocated memory, in that order:

Person* person_constructor(char *name, int year_of_birth, char *sex)
{
    Person *p = malloc(sizeof(*p));

    if (p) {
        snprintf(p->name, sizeof(p->name), "%s", name);
        p->year_of_birth = year_of_birth;
        snprintf(p->sex, sizeof(p->sex), "%s", name);
    }

    return p;
}

The code that calls the constructor must also free the memory after using it:

int main(void)
{
    Person* p1 = person_constructor("Steven", 1970, "male");

    if (p1) {
        display_person(p1);
        free(p1);
    }

    return 0;
}

Remarks:

  • Allocate according to the size of your object. You don't show the definition of the person struct, but the two string fields seem to be arrays of a fixed size, so that sizeof(struct Person) already includes them.
  • I've used snprintf instead of strcpy, becuse it ensures a null-terminated string that does not overflow the memory.

Upvotes: 1

Clifford
Clifford

Reputation: 93564

Your person_constructor() is seriously confused. You set pptr to point to p, only to overwrite it with the pointer to an uninitialised dynamic memory block (with incorrectly determined size).

    // Allocate the structure memory
    Person* pptr = malloc( sizeof(Person) ) ;

    // Assign the structure members
    strcpy( pptr->name, name ) ;
    pptr->year_of_birth = year_of_birth;
    strcpy( pptr->sex, sex ) ;

    // Return a pointer to the allocation
    return pptr ;


Upvotes: 1

Related Questions