c-programing 질문.

Zero Cool의 이미지

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main(void)
{
	char str1[100];
	char str2[10];
	char buffer_test[100];
 
	fputs("Please input any sentence: " , stdout);
	fgets(str1 , sizeof(str1) , stdin);
 
	printf("\n");
 
	strncpy(str2 , str1 , sizeof(str2)-1 ); // copy
	str2[sizeof(str2)-1] = '\0'; // This is the last index of str2.
 
	fputs("The sentence that copied: " , stdout);
	printf("%s" , str2);
 
	system("PAUSE");
	return 0;
}

=> 입력받은 문자열을 복사해서 다시 출력해주는 간단한 프로그램입니다. 프로그램상 문제점은 없습니다.
하지만 "str2[sizeof(str2)-1] = '\0' 구문을 주석처리 하면 어떤 결과가 초래 될것인가?" 라는 질문에 답하기 위해[책에서 해보라고해서 한번 해 본것 입니다..(열혈강의 c 프로그래밍)]
해당 구문을 주석 처리하고 컴파일한후 프로그램을 실행하면서 '의아한 부분' 을 발견했습니다. 바로 printf("%s" , str2); 구문에 의해서 출력되어 지는 부분입니다.

▼[str2[sizeof(str2)-1] = '\0' 구문 주석처리 했다는 가정 하에 프로그램 실행 예]▼ (출력 결과 그대로 입니다)

Please input any sentence: hello world

The sentence that copied: hello woruhello world
계속하려면 아무 키나 누르십시오.......

=> str2같은 경우 배열의 크기가 10이라서 hello wor(쓰레기값) 이라는 결과가 출력 될것이라고 예측 했었습니다. 하지만 출력결과는 완전 딴판이었 더군요..
문자열(str2의 배열) 끝에 null문자가 없는대 모양새는 이상하지만 문자열을 출력했다는 것과, str2보다 크기가 큰 문자열이 출력되었다는 점..이 2가지를 도대체 어떻게 설명을 해야 할지 모르겠습니다..


raymundo의 이미지

그 쓰레기값이 우연히 'u'의 코드값이었나보죠.

그리고 printf 는 그저 문자열의 시작 주소를 인자로 받을 뿐이고(str2는 배열의 이름이고
배열의 이름이 단독으로 수식으로 쓰였기 때문에 첫 원소의 주소로 해석됩니다)
%s 포맷을 처리할 때는 문자열의 시작주소부터 시작해서 널 캐릭터가 존재할 때까지 쭉
따라가면서 그 내용을 출력할 뿐이고, str2 배열의 크기가 몇인지는 알 수도 없고 알려고 하지도 않습니다.

아마도 main 함수의 지역변수들이 메모리에 할당될 때
arr2가 할당된 10바이트 바로 뒤에 arr1이 할당된 걸로 보이고요.

결과적으로 printf 는
- arr2 의 시작주소를 받아서
- 거기서부터 처음 복사된 "hello wor" 9글자와,
- 그 다음 바이트에 있던 쓰레기값 'u' 와,
- 그 다음 바이트에 있던 arr1의 첫 글자 h와
- 그 뒤를 이어 나머지 전부까지 출력하고
- "world"와 아마 그 뒤에 있었을 '\n'까지 출력한 후
- 그 뒤에 있는 '\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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.