2012-09-10 1 views
5

이 유사한 문의가 많이 있지만, 내 경우에는 내가 작동하지 않는 것을 이해하지 않습니다를 sizeof의 char * 배열/C++

int mysize = 0; 
mysize = sizeof(samplestring)/sizeof(*samplestring); 
std::cout << mysize << '\n' << samplestring; 

이 출력 :

4 

Press 'q' to quit. 

그게 어떻게 가능해? 4 확실히이 문자열의 크기가 아닙니다. 나는 심지어 같은 결과, 다음과 같은 시도 :

mysize = sizeof(samplestring)/sizeof(samplestring[0]);

편집 : 좋아,이 선언이다 : 나는 C++에있어

char *samplestring = "Start."; 

가,하지만 난 기능을 사용해야 만 accept char *. 나중에 코드에서 내가 좋아하는, 그 변수에 새로운 문자열을 할당합니다

samplestring = "Press 'r' for red text."; 

예, 컴파일러는 나에게 경고를 제공하지만, 나는 내가 그들을 덮어 쓸 수없는 경우 나 다른 문자열을 사용하는 방법에 대해 아무 생각이 ...

+8

어떻게'samplestring'이 선언 되었습니까? –

+0

여기서'samplestring'의 정의는 무엇입니까? – phoxis

+2

당신은 가장 중요한 정보를 남길 수있었습니다! – Arkadiy

답변

13

4은 문자열의 크기가 아닙니다. 왜냐하면 samplestring은 문자열이 아니기 때문입니다. 그것은

4. C++에서이 std::stringlength() 방법을 사용하는 것, 정확하게, 그 크기 (플랫폼)에 4 일 (char의 크기)로 나눈하는 char*입니다.

C에서는 NULL 종료 문자 포인터를 매개 변수로 사용하는 strlen을 사용합니다.

+0

다양한 플랫폼에서 char *의 크기를 확인할 수있는 좋은 참조 (예 : 웹 페이지)가 있습니까? – Pyderman

0

당신은 char에 포인터의 크기를 묻습니다. 그래서 32 비트 시스템을 사용하고있는 것 같습니다.

당신이 C++를 사용 표준 : : 문자열을 사용하는 경우 :

std::string samplestring("Hello world"); 
std::cout << samplestring.size() << std::endl; 
+0

하지만 나는 앞뒤로 몇 가지 일을해야합니다. 그렇다면 어떻게 char *을 적절한 C++ 문자열에 넣고, 내 작업을 수행 한 다음 다시 char *로 보낼 수 있습니까? – Abalieno

+0

std :: string samplestring (your_c_string); samplestring.c_str(); –

0

요소의 sizeof 연산자는 해당 개체에 할당 된 메모리의 크기를 반환합니다. 당신의 예에서 문자열은 아마도 메모리의 크기가 당신은 아마 당신의 응용 프로그램에서 원하는 방법은 크기를 반환

strlen(samplestring); 

4. 인 경우

samplestring[4] 

로 어딘가에 선언 null 종료 문자열 (종료 없음)

4

문자열 상수를 만드는 두 가지 방법이 있으며, 첫 번째 방법에서만 기술이 작동합니다. 첫 번째는 컴파일 할 때 크기를 얻을 수있는 문자 배열을 만들고 다른 배열은 문자 배열에 포인터 인 포인터를 만듭니다. 당신이 그것을하고있는 방법은 당신에게 포인터의 크기를 제공하는 두 번째 경우의 크기를 가지고 시도

char samplestring[] = "hello"; 
char * samplestring = "hello"; 

. 32 비트 빌드에서 포인터의 크기는 4 자입니다. 즉 포인터는 4 자와 동일한 양의 메모리를 사용합니다.

다음은 항상은 올바르게 끝나는 문자열에 대해 올바른 길이를 제공하지만 속도는 느립니다.

mysize = strlen(samplestring); 
+1

Note (op의 경우) : 함수에 전달하면 첫 번째 포인터가 포인터로 쇠약하게되므로'sizeof'는 동일한 컨텍스트에서만 예상 한 결과를 제공합니다. –

+0

@LuchianGrigore, 지적 해 주셔서 고맙습니다. –

1

마치 포인터가 아니라 배열로 보입니다. 프로그램을 필요로하는 경우 배열은 포인터로 변환됩니다, 그래서 당신은 얻을 것이다 :

size_t size(char * p) { // p is a pointer 
    return sizeof(p)/sizeof(*p); // size of pointer 
} 

size_t size(char p[]) { // p is also a pointer   
    return sizeof(p)/sizeof(*p); // size of pointer 
} 

sizeof (char) == 1 때문에, 분할 여기 중복,하지만; 포인터가 더 큰 유형 인 경우 예기치 않은 결과가 발생합니다.

C에서

++ (하지만 분명하지 C), 당신은 템플릿 매개 변수로 배열의 크기를 추론 할 수 있습니다

template <typename T, size_t N> 
size_t size(T (&)[N]) { 
    return N; // size of array 
} 

을하거나 크기를 추적 할 std::vectorstd::string 같은 클래스를 사용할 수 있습니다.

C에서는 strlen을 사용하여 0으로 끝나는 문자열의 길이를 찾을 수 있지만 대부분의 경우 배열 크기를 직접 추적해야합니다.

4

우선 sizeof(samplestring[0])sizeof(*samplestring)과 같으며 둘 다 samplestring 배열의 첫 번째 요소 크기를 반환합니다. 그리고 samplestring이 문자 배열 인 것으로 가정하면 sizeof(char)은 1로 정의됩니다.

samplestring은 (는) 표시되지 않습니다. 그것은 다음 중 하나 일 수,

char const *samplestring = "Hello, World!"; 

또는

char *samplestring = malloc(...); 

또는 samplestring의 유형 char *입니다 처음 2의 경우

char samplestring[10]; 

, 그래서 sizeof(samplestring) 반환 sizeof(char *)하는, 플랫폼에 따라 다릅니다.

세 번째 경우에 samplestring의 유형은 char[10] (10 자 배열)이지만, char *을 매개 변수로 사용하는 함수를 호출하면 문자 배열은 의 첫 번째 요소를 가리키는 포인터 인이됩니다. 정렬. 이 경우 함수 내에 sizeof을 인쇄하려고해도 여전히 포인터 크기가 인쇄됩니다.

원래 배열의 크기를 함수 내에서 인쇄하려면 함수 매개 변수가 원래 배열 유형에 대한 포인터 여야하며 형식에 원래 배열의 크기가 포함되어야합니다.

#include <stdio.h> 

void foo(char (*arr)[42]) 
{ 
    printf("%u", (unsigned)sizeof(*arr)); 
} 

int main() 
{ 
    char arr[42]; 
    foo(&arr); 

    return 0; 
} 

출력 :

42 

이 함수에 전달하고 많은 경우에 바람직하지 않다 수 배열의 크기를 고정. 다른 해결책은 배열을 직접 추적하는 것입니다 (또는 NULL 종료 문자열이있는 경우 strlen을 사용하십시오).

+0

+1 함수에서'sizeof'를 사용하면 원래 배열의 크기를 반환하지 않는 이유를 잘 설명 할 수 있습니다. – Serrano