동적 메모리 할당에 관하여..

ppappa의 이미지

typedef struct
{
  int id;
  void *data;
} event_struct

void func1()
{
  event_struct *event = malloc(sizeof(event_struct));
  data_struct *data = malloc(sizeof(data_struct));
  event->id = ...;
  event->data = data;
...
  func2(event);
...
}

void func2(event_struct *event)
{
  free(event);
}

제가 개념이 잘 안잡혀서 몇가지 질문이 있습니다^^

1.
위와 같이 func1()에서 동적 메모리 할당을 했을 경우
free()할 때 event만 해주면 되는건지요?
아니면 data도 같이 free()해줘야 하는지요?

2.
또하나 위의 func2()에서 인자로 받은 녀석을 free()해줘도 문제가 없는지요?
func1()의 event라는 변수 자체는 func1()의 stack 변수이고
그 변수가 가르키는 메모리 영역은 heap 영역일텐데요
이 경우 func1() 함수가 종료됨과 동시에 event라는 stack 변수는 사라지겠지만
그렇더라도 event가 가르키던 heap 영역의 메모리를 func2()의 인자로
받을 경우 func2()에서 free()해도 문제가 안되겠죠?

3.
2.와 비슷한 질문인데요 임베디드 시스템에서 func1()과 func2()가 각각 별도의 task일 경우

void func1()
{
  event_struct *event = malloc(sizeof(event_struct));
  data_struct *data = malloc(sizeof(data_struct));
  event->id = ...;
  event->data = data;

...
  func2(event);
  free(event);
...
}

void func2(event_struct *event)
{
...
  handle_event(event);
...
}

이렇게 func2(event)와 같이 인자로 넘겨주고 나서
바로 free(event)하면 func2() task에서 이 event를 데이타로
무슨 작업을 하려고 했을때 스케쥴링 문제로 인해 func2()가 제대로
데이타를 처리하기 전에 func1()의 free()가 먼저 수행되면
문제가 발생할 수 있겠지요?
이 경우 handle_event() 루틴 안에서 이를 free(event)해도 되는지요?
sangwoo의 이미지

perihk wrote:
typedef struct
{
  int id;
  void *data;
} event_struct

void func1()
{
  event_struct *event = malloc(sizeof(event_struct));
  data_struct *data = malloc(sizeof(data_struct));
  event->id = ...;
  event->data = data;
...
  func2(event);
...
}

void func2(event_struct *event)
{
  free(event);
}

제가 개념이 잘 안잡혀서 몇가지 질문이 있습니다^^

1.
위와 같이 func1()에서 동적 메모리 할당을 했을 경우
free()할 때 event만 해주면 되는건지요?
아니면 data도 같이 free()해줘야 하는지요?


네, 둘 다 각각 free() 해 주셔야 합니다.

Quote:

2.
또하나 위의 func2()에서 인자로 받은 녀석을 free()해줘도 문제가 없는지요?
func1()의 event라는 변수 자체는 func1()의 stack 변수이고
그 변수가 가르키는 메모리 영역은 heap 영역일텐데요
이 경우 func1() 함수가 종료됨과 동시에 event라는 stack 변수는 사라지겠지만
그렇더라도 event가 가르키던 heap 영역의 메모리를 func2()의 인자로
받을 경우 func2()에서 free()해도 문제가 안되겠죠?

네, 문제 없습니다. :-)

Quote:

3.
2.와 비슷한 질문인데요 임베디드 시스템에서 func1()과 func2()가 각각 별도의 task일 경우
void func1()
{
  event_struct *event = malloc(sizeof(event_struct));
  data_struct *data = malloc(sizeof(data_struct));
  event->id = ...;
  event->data = data;

...
  func2(event);
  free(event);
...
}

void func2(event_struct *event)
{
...
  handle_event(event);
...
}

이렇게 func2(event)와 같이 인자로 넘겨주고 나서
바로 free(event)하면 func2() task에서 이 event를 데이타로
무슨 작업을 하려고 했을때 스케쥴링 문제로 인해 func2()가 제대로
데이타를 처리하기 전에 func1()의 free()가 먼저 수행되면
문제가 발생할 수 있겠지요?
이 경우 handle_event() 루틴 안에서 이를 free(event)해도 되는지요?

스케줄링으로서 문제가 생기는 경우는, 공유 데이터를 놓고 둘 이상의
프로세스끼리 race가 일어나는 경우입니다. 지금과 같은 경우에서는
한 프로세스 안이므로, func2()가 리턴한 뒤에 free()가 실행되는 것이
보장되는 걸로 알고 있습니다. (임베디드 시스템..이란 말이 좀 꺼림칙하긴 하지만)
그러므로 지금 코드 자체로도 문제가 없다고 봅니다.
물론 handle_event() 안에서 해도 제대로 free() 가 될 것입니다.

----
Let's shut up and code.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.