간단한 C언어 문자열 입력에 대한 질문인데요ㅠ

newredmoon의 이미지

C언어에서 문자열을 입력받을 때,

char* text; //char*형 text 선언

text = (char *)malloc(sizeof(char)); // 동적메모리 할당

scanf("%s",text); //문자열을 받음

이런 코드로 문자열을 받으면 문자열의 길이와 상관없이 문자열을 받을 수 있자나요,,

이게 메모리상 어딘가에 문자열이 저장되고 그 시작주소를 text가 가르킨다는 것은

대충 알겠는데, 정확한 원리를 모르겠습니다.

또 free (text); 를 하면 런타임오류가 나던데, 이런식으로 문자열을 받으면

동적메모리 해제를 할 수 없는 건가요??

또한 malloc 함수를 사용하면 stack이 아닌 heap 영역에 공간을 할당한다고 들었는데,

그럼 heap영역을 사용하는 다른 변수같은 것들에는 영향을 미치지 않나요?

anster의 이미지

제가 아는 한도 내에서 설명 드리겠습니다..

우선 저런방식으로 메모리를 할당하게되면 1 byte, 즉 sizeof(char) * 1 만큼의 메모리만이 할당됩니다.
따라서 text 변수는 char 형 변수이고, 길이가 1인 char a[1] 과 같은 배열..(배열이라 부르기도 무색한ㅠ_ㅠ)을 가리키게 됩니다.

heap 영역에서 메모리를 할당할 때 빈 공간에 할당하였기 때문에 다른 변수들에는 영향을 미치지 않고..

실행시에는 어찌어찌해서(할당된 1byte 이후의 영역을 강제로 덮어쓴다던지, 컴파일러가 추가로 할당해준다던지) 실행이 되지만 메모리를 해제할때는 자신이 가르키고 있는 영역 이후에도 데이터가 있기때문에 에러 메세지가 뜨는 것 같습니다..

에러메세지도 자세히 보면... 내용이

HEAP CORRUPTION DETECTED

the application wrote to memory after end of heap buffer

다음과 같이 되어있는데.. 해당 프로그램이 주어진 heap 영역(최종적으로 할당되었으므로 heap의 끝부분이 되겠지요..)을 넘어섰다는게 감지됬다고 하네요..

결론만 말하자면.. (char*)malloc(sizeof(char)) 을 (char*)malloc(sizeof(char)*150) 으로 고쳐주시면 됩니다.. 메모리 사이즈가 부족해서 오류가 나는거에요..

===================

복군의 이글루
http://anster.egloos.com

===================

복군의 이글루
http://anster.egloos.com

newredmoon의 이미지

답변 감사드립니다~

그럼 만약 저상태로 사용한다면, heap에 잡혀있는 공간은 해제해주지 못했으니까

계속 공간을 차지하고 있다가 재부팅을 해야 공간을 비워줄 수 있는건가요??

mg2000의 이미지

공간이 낭비되는 것 또한 당연하고요.

할당된 공간을 넘어서 사용한다는 것은 다른 메모리 영역을 침범한 것이니 단순히 메모리 공간의 낭비 뿐만 아니라 프로그램 자체가 불안정하게 되겠죠.

jick의 이미지

굉장히 흔한 오해인데 요즘 쓰이는 거의 모든 OS는 프로그램이 종료될 때 그 프로그램이 사용하던 메모리를 자동으로 해제하는 기능을 갖추고 있습니다. 여기에는 윈도우즈, linux, 각종 unix, Mac OS 등등이 포함됩니다. (이 이야기 kldp에서만 서너 번 한 듯. -.-)

(MS-DOS나 핸드폰 시스템을 타겟으로 개발한다면 그 가정이 먹혀들지 않을 수도 있습니다.)

newredmoon의 이미지

감사합니다 ^^ 앞으로 안심하고 사용할 수 있겟네요

gurehf의 이미지

char* text // 스택 영역에 포인터 변수 4byte가 잡힙니다.

(char*)malloc(sizeof(char));
//malloc 함수의 매개변수로 sizeof(char)==1과 같으므로
//heap 영역에 1byte가 잡힙니다.
//(char*) 이 heap 영역의 1byte의 주소를 리턴합니다.

text = (heap area) // 위 리턴된 주소를 가리킵니다.

scanf("%s",text);

ex) asdf 라는 문자열 상수를 입력 받습니다.

text = (statck area) // 문자열 asdf의 a주소 값을 가리킵니다.

free(text); // heap 영역이 아닌 stack 영역을 해제하기
때문에 에러가 난다고 생각했으나.

------------------------------------------------------------
위의 내용을 읽고

(char*) malloc (char*3); // 3byte 할당
scanf("%s",text); // as 입력

즉 정리를 하자면 다음과 같습니다.

(할당한 메모리 량)-1 만큼의 문자열을 입력하면 문제가 발생하지않습니다.

즉 이를 보아서 널문자를 고려하지 않아 발생된 논리 오류라 생각합니다.

gurehf님..의 이미지

(char*)malloc(char*3);이 아니라 (char*)malloc(sizeof(char)*3);아닌가요..

댓글 달기

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