/********************************************* This code illustrates what goes wrong when we do a shallow copy instead of a deep copy. See the (wrong) implementation of function copy_person, and the output of the program. *********************************************/ #include #include #include "person_wrong.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]; } return result; } struct date input_date() { struct date result; printf("please enter month day year:\n"); scanf("%d %d %d", &(result.month), &(result.day), &(result.year)); return result; } void print_date(char * name, struct date d1) { printf("%s = %d/%d/%d\n", name, d1.month, d1.day, d1.year); } struct date copy_date(struct date input) { struct date result = input; 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)); printf("please enter date of birth:\n"); result.dob = input_date(); return result; } void print_person(char * name, struct person p1) { printf("%s name: %s\n", name, p1.name); printf("age = %d\n", p1.age); print_date("date of birth = ", p1.dob); } // Note: This is the WRONG way to copy a person. Since // name is a pointer, we need to make a DEEP copy, // but this function only makes a SHALLOW copy. struct person copy_person(struct person p1) { struct person result = p1; return result; } void change_age(struct person p1) { printf("please enter new age:\n"); scanf("%d", &(p1.age)); } int main(void) { struct person p1 = input_person(); struct person p2 = copy_person(p1); // change the first letter of the name of p1 to 'C' p1.name[0] = 'C'; // change the age of p1 to 40 p1.age = 40; print_person("p1", p1); print_person("p2", p2); // note, in the printout, that p2.age is not changed, // but p2.name has been changed, because it is equal // to p1.name. free(p1.name); // note that, since p2.name = p1.name, we should NOT free p2.name }