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

익명 사용자의 이미지

에를 들어

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는 말록할당된 배열 형식이아닌
읽기전용인 포인터로 문자에대한 주소만 복사가 된것인가요..???

...!의 이미지

질문을 다시 해보세요. 이런 식으로 질문해서는 뭘 잘못한건지 알 방법이 없잖아요. 개념을 잘못 알고 있는지, 코딩 실수가 있는지, 특정 함수의 사용법을 잘못 알고 있는지 등등 여러가지 가능성 중에 무엇이 문제인지 알 수가 없어요. 더 근본적으로 문장들이 전혀 의미를 전달하고 있지 않아요. 그냥 문자들의 나열이지 말이 아닌게지요. 글 잘 쓰는 능력이 프로그래밍 잘하는 능력과 상통합니다. i) 실제로 컴파일해서 실행할 수 있는 ii) 문제를 재현하는 iii) 가장 짧은 코드를 만들어서 올리세요. 이렇게 정리하는 과정부터가 문제를 이해하고 해결하는 첫 단계입니다.

익명 사용자의 이미지

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
typedef struct 
{
	int a;
	char *b[2];
	char c;
 
}test;
 
void main()
 
{
	int i=0;
	int j=0;
	test *p , *q;
 
	p=(test *)calloc(sizeof(test),2);
	q=(test *)calloc(sizeof(test),2);
 
	for(j=0;j<2;j++){
		for(i=0;i<2;i++){
			p[j].b[i] = (char*)malloc(sizeof(char)*50);
		}
	}
	for(j=0;j<2;j++){
		for(i=0;i<2;i++){
			printf(":");
			scanf("%s",p[j].b[i]);
			rewind(stdin);
		}
	}
 
	memcpy(q,p,sizeof(test)*2); //q를 p에다 복사
 
	for(j=0;j<2;j++){
		for(i=0;i<2;i++){
			free(p[j].b[i]);	
		}
	}
	/*        이 부분이 에러!
	for(j=0;j<2;j++){
		for(i=0;i<2;i++){
			free(q[j].b[i]);	
		}
	}
	*/
	free(p);
	free(q);
}
 
저기서 q안부분 free시켜줄라하면 에러가 뜹니다.
...!의 이미지

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를 사용하는 루프는 지금 문제의 본질과 아무 관계도 없습니다. 질문하실 때에 그 부분은 빼버리는 것이 더 좋았겠지요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.