#include #include #include "person3.h" int string_length(char * my_string) { int counter = 0; while(1) { if (my_string[counter] != 0) { counter++; } else { break; } } return counter; } char * copy_string(char * input) { int length = string_length(input); char * result = (char *) malloc(sizeof(char) * (length + 1)); int i; for (i = 0; i < length; i++) { result[i] = input[i]; } result[length] = 0; return result; } struct person input_person() { struct person result; printf("please enter name:\n"); char * input = (char *) malloc(sizeof(char) * 1000); scanf("%s", input); result.name = copy_string(input); free(input); printf("please enter age:\n"); scanf("%d", &(result.age)); return result; } void print_person(char * name, struct person p1) { printf("%s name: %s\n", name, p1.name); printf("age = %d\n", p1.age); } struct person copy_person(struct person p1) { struct person result = p1; result.name = copy_string(p1.name); return result; } void change_age(struct person * p1) { printf("please enter new age:\n"); scanf("%d", &(p1->age)); } // foo changes the contents of p1.name. Note that foo // does not change the VALUE of p1.name, which still // points to the same memory location. void foo(struct person p1) { p1.name[0] = 'X'; } // foo2 does NOT change the value or contents of p1.name // (it is an incorrect version of foo3) void foo2(struct person p1) { p1.name = copy_string("Mary"); } // foo3 changes the value or p1->name // (it is an corrected version of foo2) void foo3(struct person * p1) { free(p1->name); p1->name = copy_string("Mary"); } int main(void) { struct person p1 = input_person(); print_person("p1", p1); foo(p1); print_person("\np1, after foo", p1); foo2(p1); print_person("\np1, after foo2", p1); foo3(&p1); print_person("\np1, after foo3", p1); free(p1.name); }