구조체 멤버에 말록할당한것을 복사 할경우...

글쓴이: 익명 사용자 / 작성시간: 토, 2017/06/10 - 3:29오후
에를 들어
struct ...
{
char *site[5];
}t;
이렇게 있다치고
t *p,*q;
p=mall(sizeof(t*10))
q=mall(sizeof(t*10))
for i= 0 to 4
p->site[i] = malloc....
을 한뒤에
memcpy(q,p,sizeof(t)*10);
이렇게 하면 p에 내용(10개의 구조체)이 q에 넣어집니다
그리고 나중에 free시켜줄때 안에있는것부터 해주면
free (site 0 ~ 4) 까지 전부 free시켜준후 이후
free (p)
를해야하는데 저는 q또한 저렇게 free를 시켜줘야하는데
q의 경우에는 site가아닌 free(q) 자체만 free가 되게끔 동작합니다.
즉 안에든 site를 free시켜줄경우 heap영역 관한 에러가 뜨게 됩니다.
질문 드리고 싶은것은 q에다 복사할경우 q의 내용에있는 복사 된 site는 말록할당된 배열 형식이아닌
읽기전용인 포인터로 문자에대한 주소만 복사가 된것인가요..???
Forums:
질문을 다시 해보세요. 이런 식으로 질문해서는 뭘
질문을 다시 해보세요. 이런 식으로 질문해서는 뭘 잘못한건지 알 방법이 없잖아요. 개념을 잘못 알고 있는지, 코딩 실수가 있는지, 특정 함수의 사용법을 잘못 알고 있는지 등등 여러가지 가능성 중에 무엇이 문제인지 알 수가 없어요. 더 근본적으로 문장들이 전혀 의미를 전달하고 있지 않아요. 그냥 문자들의 나열이지 말이 아닌게지요. 글 잘 쓰는 능력이 프로그래밍 잘하는 능력과 상통합니다. i) 실제로 컴파일해서 실행할 수 있는 ii) 문제를 재현하는 iii) 가장 짧은 코드를 만들어서 올리세요. 이렇게 정리하는 과정부터가 문제를 이해하고 해결하는 첫 단계입니다.
간단한 코드로 예를 들면
p를 q에 복사하고 나면 i = 0, 1 과 j =
p를 q에 복사하고 나면 i = 0, 1 과 j = 0, 1에 대해서 p[i].b[j] == q[i].b[j] 입니다. 따라서 주석 처리하신 부분에서는 이미 해제(free)한 메모리 영역을 다시 해제하게 됩니다. 흔히 double free 에러라고 부릅니다.
"포인터를 복사하는 것"과 "포인터가 참조하는 메모리 영역의 내용을 복사하는 것"은 다른 겁니다.
만약에 p[i].b[j] == q[i].b[j] 가 실제로 원하셨던 바라면 주석 처리한 부분은 단순히 필요없는 부분이고, 그게 아니라 p[i].b[j] 와 q[i].b[j] 가 각각 다른 메모리 영역을 참조하도록 하고 싶었던 것이라면 p[i].b[j]에 메모리를 할당한 것과 마찬가지로 q[i].b[j]에도 따로 메모리를 할당하고 각 p[i].b[j]가 참조하는 메모리 영역의 내용을 q[i].b[j]가 참조하는 메모리 영역에 복사해줘야겠지요.
현재 구현하신 바와 같은 복사는 얕은 복사(swallow copy)라고 부릅니다. p를 q에 복사할 때에 멤버 포인터들도 단순히 복사하는 거지요. 그러면 결과적으로 p와 q의 멤버 포인터들이 같은 주소를 참조하게됩니다. 메모리를 공유하는 겁니다. 그리고 위에 설명드린 것과 같은 복사를 깊은 복사(deep copy) 라고 부릅니다. p와 q의 멤버 포인터들은 서로 다른 메모리를 참조하게되지만 참조하는 메모리의 내용은 같게됩니다.
둘 다 상황에 따라 쓸모가 있습니다. 풀어야할 문제가 어떤 복사를 필요로 하는지 잘 생각해야겠지요.
그리고 scanf를 사용하는 루프는 지금 문제의
그리고 scanf를 사용하는 루프는 지금 문제의 본질과 아무 관계도 없습니다. 질문하실 때에 그 부분은 빼버리는 것이 더 좋았겠지요.
댓글 달기