[완료]c 언어 출력 에러를 바로 잡아 주세요

ahsan의 이미지

요즘 동영상으로 C 언어를 배우고 있는데
강의내용과 실제로 실행해 본 결과가 다르게 나와서 문의드립니다.

#include
void main()
{
char *p = "sang";
char *q = p;
int i;
for(i=0; i<4; i++)
printf("%c", *(p+i));
putchar('\n');
for(i=0; i<4; i++)
printf("%c", p[i]);
putchar('\n');
printf(p);
putchar('\n');

q[1] = 'u';
printf("%s", p);
}

실행결과
sang
sang
sang
Segmentation fault

강의에서는 마지막에 printf로 찍으면 'a'가 'u'로 변해서 'sung'이 출력된다고 하는데
저는 Segmnentation fault가 나옵니다. 뭐가 잘못된 것일까요?
아시는 분들 부디 가르침 부탁드립니다.

정태영의 이미지

char *p = "sang";

char p[] = "sang";

오 비꿔보세요. readonly영역에 있는 값을 바꿀려고 시도해서 생긴 일입니다.

--
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

ahsan의 이미지

c 언어를 막 배우는 중이라 포인터에 대한 개념이 아직 없어서
뭐가 잘못되었는지 모르겠습니다.
답변 감사드립니다.

정태영의 이미지

포인터에 대한 개념은 별로 중요하지 않습니다. 그냥 저렇게 쓰면 안된다고 기억하세요.

char* ptr="1234";

이런 식으로 선언할 경우 메모리의 readonly영역에 1234란 값을 할당하고, 그 주소를 ptr에 저장합니다.

char ptr[] = "1234";

하지만 이렇게 선언할 경우 메모리의 rw영역에 1234란 값을 할당하고 그 주소를 ptr에 저장합니다.

당연하게도 readonly영역에 있는 값을 변경하려고 하면 에러가 나겠죠. gcc 등에선 옵션을 통해 두 선언이 동일한 동작을 하도록 만들 수 있지만, 그냥 저렇게 쓰는건 옳지 않다고 생각하시는게 더 좋을거 같아요.

--
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

klara의 이미지

정말로 강의가 저렇게 되어있다면 지적해야겠네요.
char *p = "sang"; 를 char p[] = "sang";로 고치고 해보세요.
p는 상수문자열"sang"을가리키고 q=p 이기때문에 상수인 q[1]에 대해서 q[i] = 'u'라고 하는 것은 불가능합니다.
문자열이 아니라 숫자로 표현해보자면 1 = 2라고 쓰고 있는것과 마찬가지인데, 이경우 매우 악질적인 것이 포인터이기 때문에 컴파일시에 잡아낼수가 없다는 것입니다.
상수문자열에 대한 포인터는 반드시 const char *p = "sang"과 같이 하여, 수정할수 없게 하는것이 좋습니다.
참고로 char p[] = "sang";라고 하면 문자(배)열 p를 선언하고 그 내용을 "sang"으로 초기화한다는 뜻이기때문에 p[1]이나 q[1]은 수정가능한 변수입니다.

ahsan의 이미지

char *p = "sang";
이 표현은 p를 초기화하는 것이 아니라 상수를 정의하는 것이군요?
가르침 덕분에 포인터에 대해 조금씩 이해하게 되는 듯 합니다.
감사드립니다.

댓글 달기

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