[C] '지역변수의 포인터와 값 반환' 에서 헷갈리는 내용이 있습니다...!

7979shin의 이미지

C언어를 공부하던 중에 다음과 같은 내용을 보았습니다.

. . . . . . . . . . . . . . .

int* function(void){
  int i = 0;
  return &i;
}

함수 function내의 지역변수인 i는
function이 return될 때는 이미 존재하지 않기 때문에,
i의 포인터 또한 반환이 불가능하다.

따라서 컴파일러는 다음과 같은 경고를 한다.
"function returns address of local variable'
(vs에서는 c4172)
. . . . . . . . . . . . . . .

그런데, 위의 함수에서
i의 포인터가 아니라 i의 값을 반환하면 오류가 나지 않습니다.
왜 i의 값을 반환할 때에는 오류가 나지 않는 것인가요??

swish95의 이미지

값은 복사하니까요. 그것이 쓰레기 값이라고 해도 말이죠

------------------------------------------------------------
ProgrammingHolic

7979shin의 이미지

앗... 코드를 잘못 썼네요.

i를 초기화해야 했는데...
(현재는 수정하였습니다!)

그런데, 값이 복사된다는게 정확히 어떤 것을 일컫는 것인가요?
i의 값이 return문의 수식에 복사되는 것인가요?

swish95의 이미지

return 문의 수식에 복사?
이말이 무슨 말인지 모르겠네요

------------------------------------------------------------
ProgrammingHolic

라스코니의 이미지

C는 함수를 호출할 때 그 호출되는 함수로부터 건네받을 값을 보관할 공간을 스택(stack)에 잡아놓고 함수를 호출합니다.
return xxx; 라는 것은 그 잡아놓은 공간에 호출된 함수가 자신을 호출한 함수에게 전달할 값을 복사하는 동작을 의미합니다. 그 뒤에는 (assembly) ret가 실행되면서 자신은 스택에서 사라지죠.

return i; 라는 것은 i가 가지고 있는 값을 스택에 잡아놓은 영역에 복사하는 것이죠. 그 함수를 호출한 쪽에서는 그 함수를 호출한 후에 그 값(return value라고 하죠)을 가지고 계속 자신의 수행을 하게 됩니다.

return &i;는 전혀 문법에 위배되지 않지만 결국에는 없어질 스택 영역을 참조로 넘겨주는 것이기 때문에 결론적으론 잘못된 동작을 하게 되죠.

7979shin의 이미지

친절한 답변 감사합니다!!
최근에 고민거리였는데... 해결되었습니다.

나빌레라의 이미지

스택을 사용하는 아키텍쳐면 라스코니님의 답변처럼 동작합니다.

만약 레지스터를 사용하는 아키텍쳐면,

리턴 시점에서 스택을 리셋하고요, (스택포인터를 함수 호출 이전으로 바꿈)
리턴 값은 레지스터에 복사 놓습니다.
함수를 호출한 쪽에서는 레지스터를 읽어서 리턴값을 가져갑니다.

----------------------
얇은 사 하이얀 고깔은 고이 접어서 나빌레라

7979shin의 이미지

방식이 하나가 아니었군요!

아직 배운게 별로 없어서 정확히는 모르겠지만,
왠지 동기부여가 되네요...
빨리 배워서 다 이해해버리고(?) 싶어요.

친절하게 답해주셔서 감사합니다!

댓글 달기

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