2009-07-11 8 views
2

내가 지금처럼 문자열의 문자를 수정합니다 ++ 2008 비주얼 C에서 일부 고전적인 C 개발 할 노력하고있어 :처리되지 않은 예외 ++ 2008

void ModifyString(char *input) 
{ 
    // Change first character to 'a' 
    *input = 'a'; 
} 

내가납니다을 문자를 변경하려고하면 처리되지 않은 예외가 발생합니다. Visual Studio 6이나 gcc에서이 작업을 수행 할 수있는 것처럼 보이지만 어쩌면 뭔가를 잊어 버리는 것일 수도 있습니다. Visual Studio는 어떻게 든 char * 값 (메모리 관리)을 전달합니다. 그렇다면 어떻게해야합니까?

+1

이 함수를 호출하는 방법에 따라 더 많이 알 수 있습니다 ... 더 많은 예제를 제공 할 수 있습니까? –

+0

NULL 인 경우. 무슨 일이야? –

답변

8

캐스트 실패에 대한

그러나 그것은 가능 문자 어딘가에 문자열 :

ModifyString("oops"); // ERROR! 

C 및 C++ 당신이 implici 수 문자열 리터럴 (유형이 const char[] 인)에서 char*으로 변환하지만 이러한 사용은 더 이상 사용되지 않습니다. 문자열 상수는 읽기 전용 메모리에 할당 될 수 있으며 일반적으로는 상수이므로 수정할 경우 액세스 위반이 발생합니다 (세그먼트 오류 또는 버스 오류라고도 함). 컴파일러가 문자열 상수를 읽기 전용 메모리에 저장하지 않으면 프로그램은 계속 작동하지만 정의되지 않은 동작입니다.

// one way: 
char mystring[] = "test"; 
ModifyString(mystring); // ok 

// another way: 
char mystring[64]; // make sure this is big enough!! 
strcpy(mystring, "test"); 
ModifyString(mystring); // ok 
+0

그래, 그게 다야. 내 드라이버가 테스트 문자열을 다음과 같이 선언했습니다. char * test = "Hello World!" 설명대로 문자 배열을 사용하도록 변경했습니다. 빠른 답장을 보내 주셔서 감사합니다. –

+0

@Brian : ModifyString에서 버퍼가 끝난 후에 작성자가 없으면 훨씬 더 큰 문제가 있음을 확인하십시오. – Paul

1

입력이 문자열 리터럴입니까? 그것은 아마 문제 일 것입니다. 그렇지 않으면 포인터가 어떻게 든 메모리의 읽기 전용 위치를 가리 키기 때문에 더 많은 코드를 게시해야합니다.

1

ModifyString이 호출되는 방법을 보지 않고도이 질문에 대답하는 것은 불가능합니다. 함수 자체는 계약이 NULL이 아닌 값을 전달해야한다고 가정하면 정확합니다. 호출 사이트가 악에 의해 const를 문자 전달 가지

  • 합격 NULL
  • 의 번호를 수행하여 당신은 아마 전달하는
+0

실수로 const char *를 함수에 전달하는 "악의적 인 캐스트"가 필요하지 않습니다. C에서 문자열 리터럴은 상수 일지라도 "char *"를 입력합니다. – newacct

+1

@newacct - 악합니다! –

+0

@newacct : 아니요, C 문자열 리터럴은'const char []'유형입니다. 문자열 리터럴에서'char *'로 암시 적 변환이 일어난다. 그 이유는 C 언어를 표준화 할 때 문자열 상수를 수정할 수 있다고 가정하는 많은 레거시 코드가 있었기 때문에 ANSI위원회는 모든 레거시 코드를 무효화하기를 원하지 않았습니다. 불행하게도 C++은이 암시 적 캐스트를 상속 받았다. –

0

이 작동하지 않는 이유를 정확하게 내가 말할 수는 없지만, 문제가 코드에, 비주얼하지 :

이 작업을 수행하는 올바른 방법은 쓰기 버퍼에 문자열을 복사하는 것입니다 사진관. 어떤 이유로 함수에 잘못된 포인터를 전달하고 있습니다. 널 포인터이거나 읽기 액세스 권한이없는 일부 주소를 가리 킵니다.

코드를 더 게시하면 (여기서 호출되는 함수는 어디에서 호출되며 어떻게 호출됩니까?) 정확한 문제를 지적 할 수 있습니다.

GCC 또는 VC6에서 작동하는 이유는 간단히 말해서 정의되지 않은 동작입니다. C++ 표준은 "this should work"또는 "crash가 발생해야 함"이라고 말하지 않습니다. 당신이 접근 할 수없는 메모리에 글을 쓰면 아무 일도 일어날 수 없다. 컴파일러와 응용 프로그램을 실행하는 시스템에 따라 액세스가 끝나는 주소가 달라집니다. 단순한 행운을 빌어 VC2008로 컴파일 할 때 액세스 위반을 일으킨 주소를 명중했습니다. GCC와 VC6에서 당신은 운이 좋지 않았고, 으로 작동하는 것처럼 보인 코드를 받았고, 그냥 쓰레기통 주소로 썼다.

관련 문제