简体   繁体   中英

char * in a struct, pointing to a char array, then using strncpy. Trying to avoid dynamically allocated memory

struct person
{
    char age [3];
    char * name;
};

char nameBuf[20];

person Natasha;
person * p_person;
p_person = &Natasha;

Natasha.name = nameBuf;

createPerson (person * resultingPerson, int p_age, const char * p_name)
{

    sprintf(resultingPerson->age, "%03d", p_age);

    strncpy(resultingPerson->name, p_name, strlen(p_name));
}


createPerson (p_person, 29, "Chelsea");

This code fails at the strncpy call. I can't use dynamically allocated memory. What is the best way to handle this? Why doesn't this work once the name* is pointing to nameBuf[20] a char array and then using strncpy?

Thank you

First off, age is only 3 and you are trying to write 4 bytes 3 digits and a null. Also, normally your length parameter to strncpy is the size of the destination minus 1 so that you have room to add null (if the source string is shorter, strncpy will add the null).

#define NAMEBUFSIZ 20
char namebuf[NAMEBUFSIZ];
typedef struct person
{
    char age [3];
    char *name;
} person;

person Natasha;
person * p_person;
p_person = &Natasha;
p_person->name = namebuf;

createPerson (person * resultingPerson, int p_age, const char * p_name)
{
    char tmpbuf[5];

    snprintf(tmpbuf, sizeof(tmpbuf), "%03d", p_age);
    memcpy(resultingPerson->age, tmpbuf, sizeof(resultingPerson->age));
    resultingPerson->name[NAMEBUFSIZ-1] = '\0';
    strncpy(resultingPerson->name, p_name, NAMEBUFSIZ-1);
}
createPerson (p_person, 29, "Chelsea");

It's still not clean, though. Can you guarantee the age will be reasonable, and that only short names (19 or fewer characters) are passed?

NOTE: changed sprintf to snprintf as the comment below is correct, sprintf is quite unsafe as your code example demonstrates

@chqrlie - you helped my track down my problem. My problem was that I didn't want a string, only a char array. When I was using sprintf it was clobbering my char * name that I had originally pointed to nameBuf[] by writing the final null char, which I was not expecting. I put it through a debugger and watched the address to the buffer change. I didn't know why that was happening until I read your comment.

I ended up writing my own itoa, without a null char, then ended by using memcpy().

Thank you for your help!

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