메모리의 쓰레기값? 에 대해서

wekiweb의 이미지

int a;와 같은 C 코드가 있다면,

이것을 초기화를 안하면 가비지값이 들어있다고 하는데요.

이것은 그 해당 메모리번지 칸을 쓰다가 치우지(?)않고 해제 된것을,
다시 할당받기에 쓰레기값이 들어있다고 하던데요.

그렇다면,

컴퓨터를 아예 하루이틀정도 안쓰다가 새로 키면, 부팅후에 메모리는 상태가 어떤가요?

안 건드린 부분들은 다 0으로 채워져있나요?

이게 궁금해서 올립니다.

 의 이미지

현재 주류 메인메모리를 구성하는 DRAM은 각 cell이 capacitor로 구성되어 있습니다.
전원이 공급되지 않으면 결국 전하가 다 빠져나와서 전압이 떨어집니다. 그런 상태를 일반적으로 0으로 놓죠.
결국 컴퓨터에 전원공급이 이제 막 시작하는 시점에서는 0으로 채워져 있다고 볼 수도 있겠습니다.

물론 어플리케이션 수준에서 초기화되지 않은 지역변수가 쓰레기값을 가지는 것과는 전혀 다른 문제입니다.

라스코니의 이미지

유저 레벨의 프로그램은 바로 물리적 메모리(physical memory)를 땡겨오는 것이 아닙니다. OS가 할당해준 가상 메모리 4G 영역을 받습니다. 할당받은 가상 메모리는 어떤 것으로 채워져 있던지 그 내용을 OS가 보장해 주지 않습니다.

int a가 global에 있는지 local 에 있는지에 따라서 초기값이 달라 집니다. global에 있으면 OS는 이것을 초기에 0으로 채워 줍니다. local 변수라면 아무것도 해 주지 않습니다. 결론적으로는 로컬 변수는 stack에 있는 영역을 사용하는 것이기 때문에 이전 stack operation이 어떤 것이었느냐에 따라서 달라질 수도 있습니다.

일반 유저는 OS의 물리적 주소에 접근할 방법이 없습니다. 커널 프로그래밍을 하지 않으면요.

.의 이미지

함수 내에서 int a; 를 하면(지역변수) x86 기준으로 현재 쓰는 대부분의 컴파일러들은
스택 포인터를 조정(빼기)해서 스택에 공간을 만듭니다. 따라서 질문자님이 보시는 쓰레기값이란
기존에 해당 스택 영역에 다른 값이 이미 써져있을 때 나오는 값입니다.

함수 콜을 하고 리턴을 하게 되면, 일반적으로 스택 포인터는 변화가 없습니다.
즉 리턴할 때 스택 포인터를 정리(epilogue)하기 때문에, caller 입장에서 보면 그대로입니다.
그렇지만 스택 포인터만 조정할 뿐이지, 스택 내의 값들을 별도로 초기화하거나 하지는 않습니다.

또한 질문자님이 main() 함수를 만들어서 그 안에 int a; 를 했다고 가정할 때
프로그램 시작이 main() 인데 왜 기존에 스택값이 써져있나요 라고 의문을 가지신다면,
보통 컴파일러는 메인 함수를 호출하기 전에 미리 다른 엔트리 함수에서 시작하도록 컴파일합니다.

윈도에서 프로그램을 디버깅해보면 main 부터가 아닌 다른 곳에서 시작해서
나중에 main 을 인자와 함께 호출해주는 것을 볼 수 있고, gcc 에서도 __libc_start_main 이라는
라이브러리 함수가 그 역할을 하는 것을 볼 수 있습니다.

즉 main 함수가 호출되기 전에 이미 다른 많은 함수들이 호출되고 리턴되는 작업을
거쳤고, 그 과정에서 main 보다 지역변수 공간을 더 많이 사용한 함수가 있다면 스택에는
그 값이 그대로 쓰레기값으로 남게 되는 것입니다.
별 관계는 없는 얘기지만 이런 값을 제대로 초기화하지 않아서 취약점이 발생하기도 합니다.

위에서 "main 보다 지역변수 공간을 더 많이 사용한 함수" 라고 얘기한 데서 눈치채셨겠지만
이 말은 즉 main 에서 지역변수를 상당히 크게 잡으면 0으로 초기화된 영역을 얻는다는 얘기입니다.
이는 컴파일러마다 다르고, 리눅스의 경우 보통 __libc_start_main 이 시스템 libc 에 의존하므로
실행하는 환경에 따라 차이가 있을 수 있습니다. (물론 이건 거의 변하지는 않습니다만)

가령 main 에서 char a[100000]; 정도로 크게 잡아서 a[0] 부터 값을 출력해보면 보통 0을 얻을 수 있습니다.
물론 끝까지 가보면 쓰레기값이 나올 것입니다.

댓글 달기

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