2011-12-30 4 views
1

나는 어딘가에 질문을 발견했다.gcc에서 세그멘테이션 오류가 발생하는 간단한 C 코드

main() 
{ 
char *p="hai friends",*p1; 
p1=p; 
while(*p!='\0') ++*p++; 
printf("%s %s",p,p1); 
} 

Answer: 
ibj!gsjfoet 

Explanation: 
++*p++ will be parse in the given order 

촬영 될 현재 P가 가리키는 위치의 값이

* 피

++ * P 검색된 값

를 증가 될 것이다; 이 발생하면 위치가 증가하여 p ++가 실행됩니다.

따라서 p가 가리키는 while 루프 초기 값은 'h'이고 ++ * p를 실행하여 'i'로 변경되고 포인터가 다음 위치로 이동합니다. 점 'a'는 'b'와 비슷하게 변경됩니다. 마찬가지로 공백은 '!'로 변환됩니다. 따라서 p에서 값은 "ibj! gsjfoet"이되고 p는 '\ 0'에 도달하고 p1은 p를 가리키므로 p1은 아무 것도 인쇄하지 않습니다.

p1에 대한 설명이 잘못되었습니다. p1이 "hai friends"를 출력하고 p의 출력이 주어진 것처럼 좋다고 생각합니다.

하지만 GCC 컴파일러에서 동일한 코드를 실행하려고 할 때, 그 여기 segmentatiion 오류

를주고 내가 실행하려고 정확한 코드 ..

#include<stdio.h> 
int main() 
{ 
char *p="hai friends",*p1; 
p1=p; 
while(*p !='\0') ++*p++; 
printf("%s %s",p,p1); 
return 0; 
} 

가능 편집하는 경우입니다 제목, 상황을 더 명확하게 설명하는 적절한 제목을 찾을 수 없습니다.

는 편집 :

나는 Mysticial에 의해 제안 수정 된 코드를 실행하려고하지만 나는 출력해야한다고 생각 -

ibj!gsjfoet hai friends 

나는 P1이해야 만 P0하지만이 증가하고 있기 때문에 그것의 최초의 장소 즉 string.Please의 시작 주소로 누군가가 내가 그것을 잘못 받고 설명 할 수 있다면 ???

+1

* *는 (는) 중복되어야합니다. 그래도 게으르다. – Tom

답변

4

글쎄,이 코드는 일반적으로 읽기가 어렵 기 때문에 ++*p++과 같은 코드는 피해야합니다.

둘째, 문제는 사용자가 문자열 변경시입니다. 그건 정의되지 않은 행동입니다. 하지 마. 당신과 같은 코드를

char p[] = "hai friends"; 
char *p1; 

를 수정 :

대신,이에 선언을 변경

int main() 
{ 

    char p[] = "hai friends"; 
    char *p0,*p1; 
    p0 = p; 
    p1 = p; 
    while(*p0 !='\0') ++*p0++; 
    printf("%s %s",p0,p1); 
    return 0; 

} 
+0

고마워요.하지만 가능하다면 좀 더 설명 할 수 있겠어요. 어떻게 작동하는 거지? ??? char로 포인터를 선언했다면 문자열을 변경할 수 없지만'characetrs' 배열로 만들면 할 수 있습니다. 둘째로 나는 당신이 말했듯이 그것을 사용하려고했지만 다시 한가지 오류'lvalue rquired'.Thanx 사전에 !! –

+0

이 코드 컴파일러에 종속됩니까 ?? –

+1

그 이유는'char * p = "blah"'로 선언 된 문자열 리터럴은 정적 메모리에 저장되고 수정 될 수 없기 때문입니다. 그러나 char p [] = { 'b', 'l', 'a', 'h', '\ 0'}의 줄임말로 'char p [] = "blah" ; '는 스택에있는 배열이며 수정할 수 있습니다. – Mysticial

1

"hai friends"은 수정할 수 없습니다 리터럴 문자열입니다.

+1

예제 프로그램이 실제로 문자열을 수정하기 때문에 이것은 사실이 아닙니다. 그것이 정의되지 않은 행동이라는 점에서 신비는 정확합니다. 이 경우 값은 증가하지만 다른 시스템에서는 동작이 다를 수 있습니다. 데이터가 ROM에 있으면 값이 변경되지 않고, ROM에 쓰여지면 하드웨어가 인터럽트를 생성 할 수 있습니다. OS는 데이터를 ia32 코드에서 수행 할 수있는 RAM의 읽기 전용 세그먼트에 넣고 데이터가 기록 될 때 런타임 오류를 생성 할 수 있습니다. 아니면 완전히 다른 것. – Skizz

+2

이 문맥에서 "can not"의 의미는 "허용되지 않습니다"입니다. –

관련 문제