2011-12-30 2 views
0

다음 두 코드 조각은 오류/경고없이 컴파일되지만 실행 중에 충돌이 발생합니다. 친절하게 저를 계몽하십시오.문자열에 대한 포인터

프로그램 1 개

int main() 
{ 
    char *p= "Hello" ; 

    *p = 'B' ; 
    printf("\n%s",p); 

    return 0; 
} 

프로그램 프로그램 2 2

int main() 
{ 
    char *p= "Hello" ; 
    Char *q="mug" 
    *q = *p ; 
    printf("\n%s",q); 

    return 0; 
} 

제가 "포옹"으로 출력을 기대 하였다.

답변

8

당신이 할 때 : 당신은 문자열 리터럴을 정의

char *p= "Hello"; 

. 문자열 리터럴은 상수 데이터이며 사용자가 알았 으면이를 수정하면 정의되지 않은 동작 (종종 충돌)이 발생합니다.

const char *p = "Hello"; 

그래서 수정하려고하면 컴파일러에서 오류가 발생합니다.

지금 당신은 대신을 정의하는 경우 :

char p[] = "Hello"; 

메모리는 다음 스택에 할당되고, 당신은 그것을 수정할 수 있습니다.

int main(int argc, char *argv[]) 
{ 
    char p[] = "Hello" ; 

    *p = 'B' ; 
    printf("\n%s",p); 

    return 0; 
} 

출력 프로그램이 들어 Bello

는 스택에있을 경우에만 q 요구 사항을 확인합니다. p은 문자열 리터럴을 가리키는 포인터이기 때문에 const 문자열을 그대로 유지할 수 있습니다.

int main() 
{ 
    const char *p = "Hello" ; 
    char q[] = "mug"; 
    *q = *p ; 
    printf("\n%s",q); 

    return 0; 
} 

출력 Hug

+0

joe 님, 덕분에 – intex0075

+0

@ intex0075 님, 기꺼이 도와 주신 데 대해 감사드립니다. – JoeFish

0

두 샘플 모두 정의되지 않은 동작을 나타내는 문자열 리터럴을 수정하고 있습니다.

0

당신이 작성해야하는 것입니다 :

char p[] = "Hello"; 

위의 양식 (숯불 p는 [] = "안녕하세요") 내가 오는 값의 배열을 가지고 컴파일러를, "말해, 많은 할당하십시오 공간이 필요합니다. " 또한 int와 함께 작동합니다. 예를 들면 다음과 같습니다.

int i [] = { 1, 2, 5, 100, 50000 }; 

그러면 i는 5 개의 값 배열에 대한 포인터가됩니다.

+0

그래, 나는 그것을 게시하고 삭제 한 직후에 그것을 깨달았다. 혼란을 드려 죄송합니다. – user1118321

0

char * p = "test"형식으로 정적 문자열을 만들면 포인터의 내용을 변경할 수 없습니다. 귀하의 경우 포인터의 내용을 수정하려고하면 관찰중인 오류가 발생합니다.

0

프로그램 2에서 문자열 리터럴을 사용하지 않도록 변경했습니다. 예상대로 "포옹"을 보여줍니다.

#include <string.h> 
#include <stdio.h> 

int main() 
{ 
    char p[10]; 
    char q[10]; 
    strcpy(p,"Hello"); 
    strcpy(q,"mug"); 
    *q = *p ; 
    printf("\n%s",q); 

    return 0; 
} 
+0

이 답변입니까? –

+0

코드가 실패한 이유는 이미 4 가지입니다. 이 답변은 올바른 방법을 설명합니다. –

0

문자열 "안녕하세요"와 "얼굴은"읽기 전용 메모리에 저장하고 거기 쓰기 위해 노력하고 있습니다.

$ gcc -S a.c 
$ cat a.s 
    .file "a.c" 
    .section  .rodata 
.LC0: 
    .string "Hello" 
.LC1: 

섹션은 "rodata"(읽기 전용 데이터)입니다.

+0

Atom은 리터럴이 "코드/텍스트 세그먼트"에 저장된다는 것을 의미합니다. 그것이 RO가 된 이유는 무엇입니까? – intex0075

+0

리터럴은 데이터가 포함 된 섹션 ".rodata"에 저장되며 ELF 실행 파일의 플래그는 해당 섹션이 읽기 전용임을 나타냅니다. ".text"및 ".data"와 같은 다른 섹션도 있습니다. "readelf --sections executable_file"을 사용하여 모든 섹션을 인쇄 할 수 있습니다. "Flg"열은 섹션의 액세스 권한을 지정합니다. –