0

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.

2
  • Why does createPerson() return void* instead of t_person*? Commented Dec 9, 2022 at 18:28
  • &person should just be person, since person is already a pointer. Commented Dec 9, 2022 at 18:30

2 Answers 2

0

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

Edit:

Another issue is this line: setName(&person, string);. person is already of type t_person*. That should be setName(person, string); This doesn't throw an error or warning because the signature of setName takes a void* which can be anything:

void setName(void* person, char *name)

This should be:

void setName(t_person* person, char *name)

That way, it would have caught your mistake calling the function incorrectly.

Sign up to request clarification or add additional context in comments.

1 Comment

Now it work inside the .c file but when i come back to the main and try to call a function, inside the .c file, that print struct->name it return a segmentation fault
0

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

Comments

Your Answer

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.