2011-09-18 5 views
8

문자열을 뒤집어 봅니다.버스 오류 문제 해결

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

int main(){ 
    char *c="I am a good boy"; 
    printf("\n The input string is : %s\n",c); 
    printf("\n The length of the string is : %d\n",strlen(c)); 
    int i,j; 
    char temp; 
    int len=strlen(c); 
    for(i=0,j=len-1;i<=j;i++,j--) 
    { 
      temp=c[i]; 
      c[i]=c[j]; 
      c[j]=temp; 
    //printf("%c\t%c\n",*(c+i),*(c+(len-i-1))); 
    } 
    printf("\n reversed string is : %s\n\n",c); 
} 

코드가 Bus error : 10 출력 :

I이 시도하는 코드이다.

그러나 나는 같은 코드를 다시 작성하는 경우 : 그것은 완벽하게 잘 작동

int main(void) 
{ 
    char *str; 
    str="I am a good boy"; 
    int i,j; 
    char temp; 
    int len=strlen(str); 
    char *ptr=NULL; 
    ptr=malloc(sizeof(char)*(len)); 
    ptr=strcpy(ptr,str); 
    for (i=0, j=len-1; i<=j; i++, j--) 
    { 
     temp=ptr[i]; 
     ptr[i]=ptr[j]; 
     ptr[j]=temp; 
    } 
    printf("The reverse of the string is : %s\n",ptr); 
} 

.

첫 번째 코드가 버스 오류 또는 분할 오류를 발생시키는 이유는 무엇입니까?

+1

코드를 다시 포맷하십시오. –

+0

가능한 많은 서식을 시도했지만 정말 정렬되지 않은 방법을 알고 있습니다. – sethu

+1

4 개의 공백으로 모두 들여 쓰기하여 코드를 포맷하십시오. – SLaks

답변

16

버스 오류가 발생합니다. 많은 경우 (대부분 또는 전부는 아니지만) C 컴파일러에서 문자열 리터럴이 읽기 전용 메모리에 할당되어 있기 때문에 버스 오류가 발생합니다.

문자열을 원래대로 되돌리고 있습니다. 첫 번째 코드 스 니펫에서 문자열 리터럴에 쓰려고합니다. 별로 좋은 생각이 아닙니다.

두 번째 경우에는 malloc'd 문자열을 힙에 넣습니다. 해당 문자열을 제 자리에서 되돌려도 안전합니다.

버스 오류 대 세그먼테이션 폴트 (segfault)에 대한 질문 주석 기하려면

칙, 즉 좋은 질문입니다. 나는 둘 다 보았다. 여기에 맥에 버스 오류입니다 :

$ cat bus.c 
char* s = "abc"; int main() {s[0]='d'; return 0;} 

$ gcc --version bus.c && ./a.out 
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5659) 
Copyright (C) 2007 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

Bus error 

다른 운영 체제에서이/컴파일러는 당신이 실제로 세그먼트 폴트를받을 수 있습니다.

+0

읽기 전용 메모리를 쓰려고하면 버스 오류가 아닌 segfault가 발생한다고 생각 했습니까? 또는 OS에 특정한가요? – cHao

+0

나는 둘 다 보았다! –

+0

저기서 이상한 일을하고 계셔야합니다. :) 버스 오류를 본 적이있는 유일한 시간, 마더 보드가 나빴습니다. – cHao

1

"I am a good boy" 형태로 지정된 문자 배열은 일반적으로 상수입니다. 수정할 수 없습니다. 이것이 첫 번째 변형이 충돌하는 이유입니다. 두 번째 방법은 데이터 복사본을 만든 다음 수정하는 방법이 아닙니다.

6

힙에 복사하는 것이 하나의 옵션입니다. 그러나 로컬 (스택) 배열을 할당하려는 경우 다음을 수행 할 수 있습니다.

char str[] = "I am a good boy"; 

그런 다음 상수 문자열이 스택으로 복사됩니다.

0

char * str = "나는 좋은 아이"입니다. 리터럴로 처리하고 수정하려고하면 버스 오류가 발생합니다. const char * str = "나는 좋은 아이"와 동일합니다. 즉, 상수 문자열에 대한 포인터이며 상수 문자열을 수정하려는 것은 허용되지 않습니다.

EDIT : malloc()과 복사 한 문자열이 원래 문자열의 복사본으로 재생되고 ptr이 'const char *'유형이 아니고 'char * ptr'유형이 아니며 불평하지 않습니다.

0

C로 컴파일 ++ (g는 ++)이 오류를 방지하도록 설계된 비 CONST 숯 * 리터럴 문자열을 할당하는 중단을 보여준다

[email protected]:~/udlit_debug$ g++ ../buserr.cpp 
../buserr.cpp: In function ‘int main()’: 
../buserr.cpp:5:13: warning: deprecated conversion from string constant to ‘char*’ 
../buserr.cpp:7:61: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘size_t’ 

관련 경고 라인에 제

표시된대로 const char * 선언을 변경하면 리터럴 문자열에 할당되지 않습니다.

경고를 무시해서는 안되는 이유에 대한 교훈이기도합니다.