전화번호부 v5.0 (2)
구조체에 대한 포인터, 동적 메모리 할당
전화번호부 v5.0 (1)(구조체에 대한 포인터) 이어서 동적메모리 할당을 적용한 전화번호 프로그램을 만든다.
위 그림처럼 Person ** directory 포인터 배열에 동적메모리 할당을 한다.
#define INIT_CAPACITY 100
typedef struct person { // person은 생략가능
char *name; // 배열로 쓰기 위해 *로 선언
char *number;
char *mail;
char *group;
} Person;
Person **dicrectory;
int capacity;
int n;
void init() {
directory = (Person **)malloc(INIT_CAPCITY *sizeof(Person *));
capacity = INIT_CAPACITY;
n=0;
}
---------------
while (1) {
if (read_line(fp, buffer, BUFFER_LENGTH)<=0)
break;
name = strtok(buffer, "#");
token = strtok(NULL, "#");
if (strcmp(token, " ")==0)
number = NULL;
else
number = strdup(token);
token = strtok(NULL, "#");
if (strcmp(token, " ")==0)
email = NULL;
else
email = strdup(token);
token = strtok(NULL, "#");
if (strcmp(token, " ")==0)
group = NULL;
else
group = strdup(token);
add(strdup(name), number, email, group);
}
fclose(fp);
}
name은 필수적으로 입력된다고 가정한다. 필수입력값으로 설정
- load()
void load(char *fileName) {
char buffer[BUFFER_LENGTH];
char * name, *number, *email, *group; char *token;
FILE *fp = fopen(fileName, "r");
if (fp==NULL) {
printf("Open failed.\n");
return;
}
- add()
void add(char *name, char *number, char *email, char *group) {
if (n>=capacity)
reallocate();
int i=n-1;
while (i>=0 && strcmp(directory[i]->name, name) > 0) {
directory[i+1] = directory[i];
i--;
}
directory[i+1] = (Person *)malloc(sizeof(Person)); // 새로운 데이터를 입력 받기 전에 동적메모리 할당
directory[i+1]->name = name;
directory[i+1]->number = number;
directory[i+1]->email = email;
directory[i+1]->group = group;
n++;
}
- reallocate()
void reallocate() {
capacity *= 2;
Person **tmp = (Person **)malloc(capacity * sizeof(Person *));
for (int i=0; i<n; i++)
tmp[i] = directory[i];
free(dicrectory); // malloc되어 이전 배열에 있던 값은 더이상 쓰지 않게되므로 메모리들은 할당 해제 해주어야한다.
directory = tmp;
}
- remove()
void reomove(char *name) {
int i = search(name); // return -1 if if not exists
if (i==-1) {
printf("No person named '%s' exists. \n", name);
return;
}
Person *p = directory[i];
for(int j=1; j<n-1; j++)
directory[j] = directory[j+1];
n--;
release_person(p);
printf("'%s' was deleted suceesfully. \n". name);
}
void release_person(Person *p) {
free(p->name);
if (p->number != NULL) free(p->number);
if (p->email != NULL) free(p->email);
if (p->group != NULL) free(p->group);
free(p);
//strdup으로 묵시적으로 복사를 하였다 그렇기에 더 이상 안쓰게 되는 메모리 할당 해제를 잊을 수 있으므로 주의한다.
}
나머지는 v4.0이랑 같으며 주요하게 다른 점은 구조체 배열이 아닌 구조체 포인터를 쓴다는 점, 동적할당에 따른 안쓰게되는 메모리들에 대해 메모리 할당 해제를 필수적으로 해주어야 한다.
'CS > 자료구조' 카테고리의 다른 글
[인프런|13강] C로 배우는 자료구조 | 연결 리스트 (2) (0) | 2020.12.20 |
---|---|
[인프런|12강] C로 배우는 자료구조 | 연결 리스트 (1) (0) | 2020.11.22 |
[인프런|10강] C로 배우는 자료구조 | 전화번호부 v5.0 (1) (0) | 2020.11.19 |
[인프런|9강] C로 배우는 자료구조 | 전화번호부 v4.0 (0) | 2020.11.16 |
[인프런|6,7,8강] C로 배우는 자료구조 | 전화번호부 v3.0 (0) | 2020.11.15 |