설명좀부탁합니다...`'

ysy의 이미지

#include <stdio.h>
int main(void)
{
char ch;
int count=0;

while(++count<=5 && (ch=getchar())!=EOF)
putchar(ch);

putchar("n");

return 0;
}

1. 왜 abcdefgh 라고 입력할때에 abcde 까지만 출력되는지 이해할수가없네요
a만 출력되어야하는건 아닙니까???
a만 입력했을땐 a가 출력되는건 이해되거든요...
getchar()에 입력된 값들은 한문자이상은 버퍼에 기록되는건가요???
그래서 putchar()이 버퍼에있는 몇개의 문자도 함께 읽기때문에..
abcdefgh라고 입력했을때 abcde까지 출력되는건가요??

#include <stdio.h>
int main(void)
{
char cstr[5];
int num =5;
int i=0;
printf("Enter a string : ");
gets(cstr);
while(i<num)
{
putchar(cstr[i]);
i++;
}
return 0;
}

처리결과:
Enter a string : AppleOneTwo
세그멘테이션 오류 - core dumped

2.위의 프로그램에서 5개의 문자가 출력되어야 하지만 변수 num과 i의값이 입력되는 문자열의 영향으로 어떤 값이 될 것인지 알 수 없다. 시스템에 따라 변수가 배치되는 방법이 다를 수 있으며, 위와 같은 오류가 발생하지 않을수 있다고 하던데, 변수가 배치되는 방법은 어떤것이 있나요??? 리눅스 시스템은 어떤가요??

--두서없는 질문이였다면 죄송합니다.. 안녕히계세요!!

vacancy의 이미지

버퍼에 문자가 있는 동안은,
getchar() 의 리턴값이 EOF가 되지 않습니다.

그리고 gets는 fgets로 대치하시는것이 좋습니다.
man fgets하시면 다음의 메시지를 보실수 있으실겁니다.

Quote:
Never use gets(). Because it is impossible to tell with­
out knowing the data in advance how many characters gets()
will read, and because gets() will continue to store char­
acters past the end of the buffer, it is extremely danger­
ous to use. It has been used to break computer security.
Use fgets() instead.
alsong의 이미지

i,num이 바뀐다는 의미가 버퍼 오버플로우에 의해 바뀐다라는 것인지요?
리눅스에서 스택에 변수의 위치를 마음대로 바꿀수 있는 방법은 들어 본적이 없군요.(곰곰히 생각해보니 앞뒤로는 바꿀수 있겠군요 ^^;)
버퍼를 늘리든지 다른 함수를 쓰셔야 겠습니다.
단, i,num을 static(위치가 바뀌긴 합니다. 다른곳으로 ^^)으로 선언한다면 값의 변화를 막을 수는 있을것 같군요.
어째든 호출한 함수의 리턴값이 바뀌기 때문에 i,num의 값이 바뀌지 않더라도 코어를 피하기는 힘들것 같군요.

제가 약간의 생각이 잘못 된곳이 있었던것 같군요.
cstr[5]가 호출한 함수 안에 있다라고 생각하고 있었습니다.

리눅스의 경우
먼저 선언한 변수가 스택의 높은 번지에 들어 가는것 같군요.
즉, (컴파일러가 최적화를 위해 바꿀수 있는지는 모르겠습니다. ^^ 바뀐다면 의미가 없겠죠.)
char cstr[5];
int num =5;
int i=0;
사용하면 num과 i를 바뀌지 않을 것 같군요.

어째든 코어는 피하기 힘들것 같군요. ret값이 바뀔수 밖에 없기 때문에....
추가로 현재 소스의 형태에서는 main함수의 return 어드레스이 바뀌게 됩니다.

그나저나 백수 언제 탈출하냐... ㅡㅡ; 배고파라.

ysy의 이미지

alsong wrote:
i,num이 바뀐다는 의미가 버퍼 오버플로우에 의해 바뀐다라는 것인지요?
리눅스에서 스택에 변수의 위치를 마음대로 바꿀수 있는 방법은 들어 본적이 없군요.(곰곰히 생각해보니 앞뒤로는 바꿀수 있겠군요 ^^;)
버퍼를 늘리든지 다른 함수를 쓰셔야 겠습니다.
단, i,num을 static(위치가 바뀌긴 합니다. 다른곳으로 ^^)으로 선언한다면 값의 변화를 막을 수는 있을것 같군요.
어째든 호출한 함수의 리턴값이 바뀌기 때문에 i,num의 값이 바뀌지 않더라도 코어를 피하기는 힘들것 같군요.

제가 약간의 생각이 잘못 된곳이 있었던것 같군요.
cstr[5]가 호출한 함수 안에 있다라고 생각하고 있었습니다.

리눅스의 경우
먼저 선언한 변수가 스택의 높은 번지에 들어 가는것 같군요.
즉, (컴파일러가 최적화를 위해 바꿀수 있는지는 모르겠습니다. ^^ 바뀐다면 의미가 없겠죠.)
char cstr[5];
int num =5;
int i=0;
사용하면 num과 i를 바뀌지 않을 것 같군요.

어째든 코어는 피하기 힘들것 같군요. ret값이 바뀔수 밖에 없기 때문에....
추가로 현재 소스의 형태에서는 main함수의 return 어드레스이 바뀌게 됩니다.

i,num의 값이 변화한것은 오버플로우에 의한것이라고 들었습니다.
오버플로우라면 i,num의 값이 변화하지않나요???...
리눅스에서 테스트해보니깐 에러가 안나네요...(코어 또한 발생하지않고..)
솔라리스에서는 세그멘테이션 오류 - core dumped가 뜨더라구요...
어떤분이 방지하려면 char cstr[5]; 위치를 i와 num사이에 두면된다고 하던데...
이해가 안가네요...(잘못알았습니다. char cstr[5];를 i와 num사이에 두니깐..
코어덤프가 발생하군요!! ㅠ.ㅜ)
현재 소스의 메모리 의 변수 배치를 그려주실수있나요??
늦었지만,답변감사합니다.. ^.^

alsong의 이미지

코어가 나지 않은것은 return address가 있는 위치까지 입력되지 않았기때문에 나지 않을 수 있습니다.
많은 데이터를 넣으면 죽을수 있을겁니다.
위치와는 관계가 없습니다. 어떻게 배치하나 망가지게 되어 있습니다.
위치에 따라서 putchar에서 죽는 경우는 없을 수 있겠군요.
또 다른 문자열 대신에 같은 문자를 계속넣어도 i , num이 같은 값이 되므로
죽지 않겠지요.
조건을 만족하지 않으니까 putchar의 문장으로 들어 가지 않겠지요.

Quote:
오버플로우라면 i,num의 값이 변화하지않나요???...

cstr의 위치가 i,num의 위치보다 높은 어드레스에 있다면 i,num은 손상되지 않습니다.
0x000000                                                       0xffffffff
---------------------------------------------------------------------------
                                                             num  i  cstr ret
---------------------------------------------------------------------------
                                                                     AppleOneTwo 

이런식으로 스텍에 입력 되어 있다면
cstr에 과도하게 쓸경우라도 ... num,i는 변하지 안겠지요.

0x000000                                                       0xffffffff
-------------------------------------------------------------------
                                                             cstr num  i   ret
-------------------------------------------------------------------
                                                             AppleOneTwo
인 경우에는 변하겠죠.
소스 메모리맵이 이렇타는 건 아니구요. 예를 든겁니다.

그나저나 백수 언제 탈출하냐... ㅡㅡ; 배고파라.

댓글 달기

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