2011-02-15 8 views
1

나는 내 프로그래머의 이상한 행동을 알아 냈습니다. 알아낼 수 없습니다. 교수님이 내 프로그램에 결함이 있다는 것을 보여주었습니다. 전체 배열의 새로운 복사본을 만드는 대신 객체를 만들 때 char 포인터를 복사하기 만하면됩니다. 그는 이와 비슷한 코드로 이것을 보여주었습니다. 내가 대신 할 경우 지금문자 배열의 문자를 설정하려고 할 때 프로그램이 충돌합니다.

char sweat[] ="Sweater"; 
warenkorb = new WareImKorb(new Textil (205366,4.2,sweat,40),2,warenkorb); 
sweat[0] = '\0'; 

: 코드에 대한

char* sweat ="Sweater"; 

프로그램은 내가 땀을 시도까지 잘 실행 [0] = '\ 0'; 그것은 간단히 그 다음에 쇠퇴합니다.

그러나 이것은 작동합니다 : char cc [] = "스웨터"; char * sweat = cc;

사실, 왜 버전 1이 작동하지 않는지 이해할 수 없다는 사실이 궁금합니다. 너희들이 나를 도울 수 있기를 바란다. 그렇지 않으면 내가 이것에 대해 궁금해 할 것이다.

+0

첫 번째 버전에서 작동하지 않는 기능은 무엇입니까? 왜 std :: string 대신 char 배열을 사용하고 있습니까? – CashCow

답변

3
char* sweat ="Sweater"; 
sweat[0] = '\0' 

으로 이루어집니다. "스웨터"는 읽기 전용 메모리의 어딘가에있는 const 리터럴 데이터이며 sweat은이 데이터를 가리 킵니다. 복사본을 만들지 않습니다. 따라서 sweat[0]='\0'을 실행하면 CONSTANT 데이터의 첫 번째 문자가 변경됩니다. 따라서 오류. 그런데 좋은 컴파일러는 const을 선언문에 쓰지 않는다면 경고를 내야합니다 (예 : const char* sweater = "Sweater"). http://www.ideone.com/P47vv

char sweat[] = "Sweater"을 쓸 때 CONSTANT 데이터 인 "Sweater"에서 데이터를 복사하는 char 배열이 만들어집니다. 그 배열의 요소 자체가 수정 가능합니다!


흥미로운 일을 볼 수 없습니다 : 그래서 상관없이 (모두 같은 데이터를 가리키는) 선언 얼마나 많은 변수, 첫 번째 경우에, 그것은 CONST 데이터의 복사본을하지 않기 때문에, 주소 모든 변수에 대해 동일합니다. 이 참조 :

#include<cstdio> 
int main() { 
     char* sweat ="Sweater";  //notice the warning 
     const char* another ="Sweater"; //no warning! 
     std::printf("%p\n", sweat);  //print the address 
     std::printf("%p\n", another); //print the address 
     return 0; 
} 

출력 :

0x8048610 
0x8048610 

수단이 모두 printfs 같은 주소를 인쇄!

여기에 자신을 참조하십시오 : http://www.ideone.com/VcyM6

5

"스웨터"는 읽기 전용 메모리에 상주 할 수있는 문자열 리터럴입니다. char * 구문을 사용하면이 리터럴을 char 배열로 복사합니다. char * 구문 (실제로는 char *이어야 함)을 사용하면 원래 문자열 리터럴을 가리키게됩니다.

0

작동하지 않는 버전에서는 문자 배열을 만들지 않습니다. 포인터로만 연주하고 있습니다.

sweat[0] = '\0'이 유효한 문일 경우 sweat이 실제 문자 배열이되어야합니다.

char sweat[] = "XXXX"; 또는 문자 상수 데이터에 여기 sweatsweat[20];

0

C++ 관리되는 언어가 아닙니다. 적절한 크기가 아닌 문자 배열에 대한 포인터를 작성하지 마십시오. 더 나은 아직

char* sweater = new char[10]; 
sweater[0] = '\0'; 
delete [] sweater; 
sweater = NULL; 

또는 : 구조에

std::string sweater = ""; 
2

ASCII 아트 다음 예는 모두 더 나은 솔루션입니다! char sweat[] 버전은 메모리에 다음과 같습니다 다음 char* sweat 버전은 다음과 같습니다

 +---+---+---+---+---+---+---+---+ 
sweat: |'S'|'w'|'e'|'a'|'t'|'e'|'r'| 0 | char[8] 
     +---+---+---+---+---+---+---+---+ 

반면 :

 +---+---+---+---+---+---+---+---+ 
     |'S'|'w'|'e'|'a'|'t'|'e'|'r'| 0 | const char[8] 
     +---+---+---+---+---+---+---+---+ 
     ^
     | 
     | 
     +-|-+ 
sweat: | | | char* 
     +---+ 
맞아

하는 const char를 가리키는 char*합니다. 비 const 문자 포인터에 문자열 리터럴을 할당 할 수 있다는 사실은 C++의 정적 유형 시스템에서 거룩하지 못합니다. 저주, 역 호환성!

관련 문제