2010-01-24 3 views
2

내가 C#을, PHP 및 기타 물건에 오랜만에 ++ 다시 C로 설정 바인딩 내가 뭔가 이상한 발견C + +를 배열로 strcpy를 상수가 아닌 표현

temp.name = new char[strlen(name) + strlen(r.name) + 1]; 

temp.name = (char *)malloc(sizeof(char[strlen(name) 
    + strlen(r.name) + 1])); 

를 컴파일을 이하지 않는

컴파일러 에러

,691이다 (temp.name는 숯 *이다)

오류 C2540가 : 배열과 같은 비 상수 식 이

을 결합

사람이 문제가 될 수 있으며이 어떻게 해결 될 수있는 무엇을 알고 있나요? 고맙습니다.

+0

C++을 사용하는 경우 char 배열을 잊어 버리고 std :: string을 사용하십시오. –

+0

프로그램 텍스트가 동일하게 보이지만, 의미는 매우 다릅니다. C++에는 크기가 0 또는 런타임 값인 배열 유형이 있습니다. 그러나이 배열 타입은'new-type-id'에 의해서만 접근 가능합니다. 선언 된 배열에 대한 타입 지정자는 new-type-ids를 사용하지 않으므로이 "멋진"타입을 나타낼 수 없습니다.'new (char [strlen (name)]); 또는'new (char [0]);'를 쓰고, 컴파일러와 함께 실패하는 것을 주목하라 : 괄호는 컴파일러를'type 'new-type-id' 대신에 -id'를 사용합니다. 비슷하게,'sizeof'는'type-id'를 기대합니다. –

답변

6

sizeof(...)에는 일정한 컴파일 시간 표현식이 필요합니다. strlen은 컴파일 타임식이 아니므로 결과를 얻기 위해 실행해야하는 함수입니다. 따라서 컴파일러는 다음과 같이 선언 된 배열을위한 충분한 저장을 예약 할 수 없습니다 : 문자열의 길이 분명 5

char c[strlen("Hello")]; 

있지만, 컴파일러는 알 수 없습니다.

이 함정을 피하려면 여기 sizeof을 사용하지 마십시오. 대신 :

char* c = (char*)malloc(strlen(name)+strlen(rname)+1); 

이렇게하면 n 바이트의 포인터가 반환됩니다. sizeof(char)==1은 항상 true이므로 버퍼의 바이트 수는 저장할 수있는 문자 수와 같습니다. 다른 유형의 malloc 어레이, 배열 요소의 고정 크기의 곱 이는 괜찮

int* c = (int*) malloc(sizeof(int)*100); 

, sizeof는 컴파일 시간 표현에 적용되기 때문이다. 물론, C++ 방법은 훨씬 청소기입니다

temp.name = (char *) malloc((strlen(name) + strlen(r.name) + 1)) * sizeof(char)); 

:

int* c = new int[100]; 
0

의 malloc은 실제 크기를 계산하고 유형을 지정하는 대신에 그것을 전달해야 의미 입력으로 size_t로 필요 어쨌든 new을 사용해야 할 것이므로 실제 문제는 없습니다.

+0

1 == sizeof (char)는 항상 참이므로 곱 해줄 필요가 없습니다. –

+0

나도 알아,하지만 내가 습관적으로 나중에 유형을 바꾸고 싶을 때를 대비해서 (와이드 캐릭터 유형으로?). 그런 다음 vim에서 ": s/char/wchar_t/g"와 같은 작업을 수행 할 수 있으며 모든 것이 자동으로 수정됩니다. :-) –

+0

이것이 의도라면, 아마도'sizeof * temp.name'을 사용하는 것이 더 낫습니다. –

1

문제는 char[...]이며 배열 유형이며 C++ (및 C89) 배열 크기는 컴파일시 상수가되어야합니다. 아마도 new[] 또는 malloc()에 의해 메모리를 수동으로 할당하는 대신 std :: string을 사용해야하지만 수동 할당을 사용하려면 배열을 사용하는 대신 문자의 수로 직접 크기를 계산하고 sizeof을 사용하십시오.