구조체의 멤버변수를 바꾸는 함수 질문 다시 올립니다.
글쓴이: ShaYEL / 작성시간: 월, 2013/11/04 - 7:30오후
제가 KLDP를 보게된지가 얼마 안되서 이래도 되는건지는 잘 모르겠는데요, 낮에 올린 글이 좀 난잡하게 되어버린것 같아서 다시 글을 올립니다. 도움 부탁드리겠습니다..
"input.txt" 파일에는 "string1 string2"가 씌어져 있다고 생각하면 될 것 같습니다. new_structure 함수를 이용해서 string1과 string2를 읽어들여 각각 person이라는 구조체의 member1과 member2에 집어넣도록 하고 싶은데, 코드를 실행시켜도 person 구조체가 텅 비어있는채로 남아있습니다.
제가 짠 코드는 대충 이렇습니다
struct A { char *member1; char *member2; struct list_elem e; }; void new_structure (FILE *fp, char *data[], struct A *person) { char arr[20]; char *token; int n = 0; fgets(arr,20,fp); token = strtok(arr," "); while (token != NULL) { data[n++] = token; token = strtok(NULL," "); } person->member1 = data[0]; person->member2 = data[1]; } void main() { struct A person; char *data[2]; FILE *fp = fopen("input.txt","r"); new_structure(fp,data,&person); printf("%s\n",person.member1); printf("%s\n",person.member2); //각각 data[0]와 data[1]의 주소에 들어있는 값이 출력되기를 기대했는데 garbage만 출력됩니다. fclose(fp); }
이전글에서 조언해주신 분들 말씀처럼 new_structure함수 내에서 data를 만드는 부분이 잘못된거같은데요, 어디서 잘못된 될까요?
Forums:
코드를 보니 역시 이전 게시물을 보며 상상했던 그
코드를 보니 역시 이전 게시물을 보며 상상했던 그 문제로군요..
strtok()이 리턴하는 토큰은 새로 할당된 메모리에 있는 것이 아니고
첫호출때 넘겨받은 arr[20] 공간에 있는 것입니다.
아래 페이지를 보시면 strtok() 동작방식이 잘 설명되어 있습니다.
원본 문자열 중간중간에 구분자 자리에 NULL 문자를 넣어가면서 토큰을 잘라 리턴합니다.
http://forum.falinux.com/zbxe/index.php?document_srl=408126&mid=C_LIB
arr[20] 공간은 new_structure() 실행 시작될때 스택에 할당되고
new_structure()가 리턴하고 나면 수명이 끝나므로 곧 다른 용도로 덮여버리죠.
그 공간을 가리키고 있는 person->member1/2 내용물도 엉망이 되고요.
우선 간단히 해결하시려면,
data[n++] = token; 코드를 data[n++] = strdup(token); 정도로 바꾸면 됩니다.
strdup()은 힙에 새로 메모리를 malloc()하고 token 문자열을 복제해서 포인터를 넘겨줍니다.
person->member1/2는 나중에 프로그램 어디에선가 꼭 free()해 주셔야 한다는 것을 잊지 마시고요.
정말 감사합니다. 여러가지를 다시 깨닫게
정말 감사합니다. 여러가지를 다시 깨닫게 되네요...
링크해주신 사이트도 공부하기 정말 좋은곳같네요 여러모로 감사합니다^^
댓글 달기