c 기본질문 임돠..

oranke의 이미지

#include <stdio.h>
#include <stdlib.h>

char * getMessage1();
char * getMessage2();
char * getMessage3();
char * getMessage4();

int main( int arc, char **argv )
{

char * mesg1 = getMessage1() ;
printf(" after getMessage1() mesg->[%d] \n", mesg1 );
printf("\n");

char * mesg2 = getMessage2() ;
printf(" after getMessage2() mesg->[%d] \n", mesg2 );
printf("\n");

char * mesg3 = getMessage3() ;
char * mesg4 = getMessage4() ;

printf(" call1 : %s\n", mesg1 );
printf(" call2 : %s\n", mesg2 );
printf(" call3 : %s\n", mesg3 );
printf(" call4 : %s\n", mesg4 );

/*free( mesg1 );*/
free( mesg2 );
/*free( mesg3 );*/

return 0;
}

char * getMessage1()
{
char mesg[100];
strcpy(mesg,"hello");

printf(" before call1 : %s\n", mesg );
printf(" before getMessage1() mesg->[%d] \n", mesg );
return mesg;
}

char * getMessage2()
{
char * mesg = "hello";
printf(" before getMessage2() mesg->[%d] \n", mesg );
return mesg;
}

char * getMessage3()
{
char * mesg = (char*)malloc(5+1);
/*memset(mesg, 0x00, sizeof(mesg));*/
sprintf( mesg, "%s","hello");
return mesg;
}

char * getMessage4()
{
static char * mesg = "hello";
return mesg;
}

위 예의 출력은
before call1 : hello
before getMessage1() mesg->[804397952]
after getMessage1() mesg->[804397952]

before getMessage2() mesg->[536872952]
after getMessage2() mesg->[536872952]

call1 : 嚬억嚬억嚬억嚬억嚬억
call2 : hello
call3 : hello
call4 : hello

입니다.-------------------------------------------------

질문
1.
getMessage1(),Message3() , getMessage4() 함수의 mesg 변수값은 차례대로
stack에 저장되는값,
Heap에 저장되는 값,
초기화된 데이타영역에 저장되는값으로 알고 있는데요..

그러면 getMessage2() 함수의 mesg 값은 어디에 저장되는건가요(함수내에서초기화된 변수)?

2.
/*free( mesg1 );*/
free( mesg2 );
/*free( mesg3 );*/

heap상에 저장되지 않은 값의 변수(mesg1,mesg3)을
free 해도 왜 세그먼트 오류가 발생하지 않는 건가요?

익명 사용자의 이미지

1. getMessag2()의 mesg 값은 일단 함수내의 mesg 에 저장되고
pointer이기 때문에 주소로 return 해서 main의 mesg2에 주소로 저장됩니다.

getMessage1, getMessage2, getMessage3, getMessage4 모두
pointer에 대해서는 같은 작업을 하고 있다고 보시면 됩니다.

이 예제는 char * 에 데이타를 주는 여러 방식을 보여주기 위한 것 같군요.

2. mesg1, mesg3을 free 하더라도 오류가 나지 않는것은 pointer로 변수가 설정되어 있기때문이 아닌가 싶습니다.

==== 기타 잡생각 ====
malloc 로 메모리를 잡아 준건 모두 메모리를 잡고 있어서
많이 실행시키다 보면 core 는 나지 않지만 데이타가 깨지는걸로 알고 있구요.

그래서 mesg2 를 free를 할께 아니라 mesg3을 free 해야 하지 않을까 생각이 들구요.

function 안에서 잡아준 변수는 그 function 안에서만 활성화 되었다가 곧 지워진다고 알고 있습니다.

그래서 원칙상으로 따지자면 free를 해주지 않아도 상관없는거죠.

doldori의 이미지

oranke wrote:
1.
getMessage1(),Message3() , getMessage4() 함수의 mesg 변수값은 차례대로
stack에 저장되는값,
Heap에 저장되는 값,
초기화된 데이타영역에 저장되는값으로 알고 있는데요..

그러면 getMessage2() 함수의 mesg 값은 어디에 저장되는건가요(함수내에서초기화된 변수)?


변수가 어디에 저장되는지는 별로 중요하지 않습니다. 중요한 것은 변수의 수명(lifetime)입니다.
각 함수가 반환하는 것은 포인터이므로 포인터 자체보다는 포인터가 가리키는 문자열이
유효한지 판단해야 합니다.

getMessage1() : mesg는 자동 기억 수명(automatic storage duration)을 가지며
함수가 종료하는 순간 파괴됩니다. 따라서 main에서는 mesg에 접근할 수 없습니다.

getMessage2() : mesg는 자동 기억 수명을 가지나 그것이 가리키는 문자열은
정적 기억 수명(static storage duration)을 가지며 프로그램 실행되는 동안
계속 유효합니다. 그러나 문자열의 변경은 안됩니다.

getMessage3() : mesg는 자동 기억 수명을 가지나 그것이 가리키는 문자열은
할당 기억 수명(allocated storage duration)을 가지며 free 하기 전까지는
계속 유효합니다. 문자열의 변경도 가능합니다.

getMessage4() : mesg와 그것이 가리키는 문자열 모두 정적 기억 수명을 가지며
프로그램 실행되는 동안 계속 유효합니다. 그러나 문자열의 변경은 안됩니다.

oranke wrote:
2.
/*free( mesg1 );*/
free( mesg2 );
/*free( mesg3 );*/

heap상에 저장되지 않은 값의 변수(mesg1,mesg3)을
free 해도 왜 세그먼트 오류가 발생하지 않는 건가요?


malloc/calloc/realloc에 의해 할당되지 않은 포인터를 free하는 결과는 정의되지
않으므로 "왜?"냐고 묻는다면 "우연히"라는 답이 가장 알맞겠지요.

댓글 달기

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