i have a structure called person on header file:
typedef struct person
{
int age;
char name[42];
char *surname;
} t_person;
Also, i have two function: The first function, called by main, return a void* pointer to a strucutre of dimension equal to t_person dim. The second function is called setName and take in input the void* pointer to struct and a pointer to char.
This is the main function:
#define STRING_LEN 100
int main()
{
void* person = createPerson();
// variables for testing
int testNumber = 1;
int number = 42;
int result=0;
int number2=0;
char *string = (char *)malloc((sizeof(char) * STRING_LEN));
strncpy(string,"Marco", STRING_LEN);
setName(&person, string);
}
and this is the .c file:
#include "function.h"
#include <string.h>
void* createPerson()
{
void* newPerson=malloc(sizeof(struct person));
return newPerson;
}
void setName(void* person, char *name)
{
t_person* person_pt = (t_person*)person;
for(int i=0;i<strlen(name);i )
{
person_pt->name[i]=name[i];
}
printf("str: %s \n", person_pt->name[i]);
}
I want to set person->name but my code don't work. it fill the struct field name but it is always full of trash. I think that the problem is that i dont understand something about pointer.
CodePudding user response:
Your issue is here:
for(int i=0;i<strlen(name);i )
{
person_pt->name[i]=name[i];
}
strlen
returns the number of characters in a proper c string. That would not include the null terminator at the end of the string. After this operation, person_pt->name
will not have a null terminator at the end. Then, when this line executes
printf("str: %s \n", person_pt->name[i]);
... that %s
specifier is saying print bytes until we reach the null terminator, but you didn't copy that!
One solution, would be to change the test in the for loop to
or(int i=0;i <= strlen(name);i )
{
person_pt->name[i]=name[i];
}
That would copy the null terminator. Or you could just use strcpy
which does the same thing:
strcpy(person_pt->name, name);
CodePudding user response:
You need to terminate strings with \0
in C, that's how they know they're done (strings that use this format are said to be null-terminated). So you could change the loop in setName
to
int i;
for(i = 0; i < strlen(name); i ) {
person_pt -> name[i] = name[i];
}
person_pt -> name[i] = 0;
However, you run the risk of a buffer overflow if strlen(name)
is greater than 42, the number of characters you gave to the name field. This is unlikely, but still you should avoid it by changing the loop to this:
int i;
for(i = 0; i < strlen(name) && i < 41; i ) {
person_pt -> name[i] = name[i];
}
person_pt -> name[i] = 0;
You could also use strcpy
from string.h
, or strncpy
for a safe version, replacing the loop with this:
strncpy(person_pt -> name, name, 41);