2011-10-25 4 views
0

C에서 CMap을 구현하고 있는데,이 중 일부는 수동으로 메모리를 관리하는 연결된 목록 유형의 구조에 정보를 저장하는 것을 수반합니다. 따라서이 의 처음 4 바이트는 다음 struct에 대한 포인터이며 다음 섹션은 문자열 (키)이고 마지막 섹션은 값입니다.void *에서 C의 문자열 값을 할당하는 방법은 무엇입니까?

라고 말하면 void *e = ptr은 그러한 연결된 목록 중 하나를 정의합니다. 그런 다음 ptr + 4은 문자열 섹션의 시작을 나타냅니다. 내가 다른 문자열에 해당 문자열 값을 할당 할, 그리고 내가 지금까지했던 것은 :

char *string = (char *)ptr + 4; 

그러나, 나는이 옳다고 생각하지 않습니다.

+4

왜 구조체로 형 변환 한 다음'->'연산자를 사용하여 필드에 액세스 할 수 없습니까? – ThiefMaster

+0

문자열의 길이를 어떻게 알 수 있습니까? 0 바이트로 종료됩니까? 정확히 당신이하려는 것은 무엇입니까? 문자열의 사본을 만들려고하십니까? 아니면 그냥 액세스 할 수 있습니까? 0으로 끝나는 C 스타일의 문자열이고, 그 값에 접근하고 싶다면,'char * string = (char *) ptr + 4;'가 좋다. ('sizeof (void *)'가 4보다 좋을지라도 코드는 결국 LP64 플랫폼에서 실행되어야합니다.) –

답변

0

포인터가 항상 4 바이트 너비라고 가정 할 때 코드가 괜찮은 동일한 문자열을 가리 키려는 경우.

문자열의 내용을 복사하려면 malloc 및 strcpy를 사용하여 새 문자열을 만듭니다.

0

오프셋을 계산하는 대신 구조체를 참조하십시오.

//if data is structured this way 
struct struct_list_el 
{ 
    struct list_el * next; 
    char* str; 
    int value; 
}; 
typedef struct struct_list_el list_el; 

// than from void_pointer 
list_el* el; 
el = (list_el*) void_pointer; 

char * string; 
string = el->str; 
+0

구조체를 사용하는 경우 모든 것이 메모리에 제대로 정렬되어 있는지 확인해야합니다. 일부 아키텍처에서 버스 오류 (예 : m68k). – hochl

+0

@hochl 무엇? m68k와의 차이점은 PC가 리틀 엔디안 인 빅 엔디안이라는 것입니다.한 컴퓨터에서 다른 컴퓨터로 정수를 보내는 것보다 문제가 발생할 수 있습니다. –

+0

기억 나는 m68000에서, 비 - 짝수 주소에서 바이트보다 큰 값을 액세스하는 것은 버스 오류를 일으킬 것이다. 그러나 그것은 80 년대에 있었고, 아마도 새로운 모델은 그러한 상황에서 버스 오류를주지 않고 메모리 액세스를 분할하지 않을 수도있다. 내부적으로 두 개의 액세스로 어쨌든 컴파일러는 일반적으로 패딩 바이트를 삽입하여 모든 구조체 멤버가 액세스 가능한 오프셋 (일반적으로 바이트 이외의 다른 것)에 있도록합니다. – hochl

0

@ralu는 구조체를 사용해야합니다. 그러나 문자열을 복사 할 때는 매우주의해야합니다. C에는 C++, Java, Python과 같은 최상위 문자열 객체가 없습니다. :)

C에서 문자 포인터 (char*)는 문자열로 사용되는 경우가 많지만 실제로는 어딘가에있는 Null로 끝나는 바이트 배열에 대한 포인터 일뿐입니다. 문자 포인터를 복사하는 것은 기본 문자 배열을 복사하는 것과 동일하지 않습니다. 이를 수행하려면 사본의 문자에 대한 메모리를 제공해야합니다. 이 메모리는 스택 (로컬 배열) 또는 힙 (malloc을 사용하여 생성 된) 또는 다른 버퍼에있을 수 있습니다.

대상 버퍼에 저장할 수 있도록하기 전에 문자열 길이를 측정해야합니다. 종료 널 (null)을위한 공간이 있도록 길이에 하나를 추가하십시오.

또한 표준 라이브러리 함수 (strlen, strcpy, strncpy, strcat, snprintf, strdup 등)는 종료 null과 관련하여 약간 호환되지 않습니다. 예를 들어, strlen은 종료 널을 제외한 문자 수를 반환하므로 버퍼는 물건을 보관하기 위해 반환하는 것보다 1 바이트 더 커야합니다. 또한 strncpy는 snprintf가 수행하는 동안 널 종료를 보장하지 않습니다. 이러한 함수와 C 문자열을 잘못 사용하면 오늘날 컴퓨터 시스템의 보안 침해 (버그는 말할 것도 없음)가 많이 발생합니다.

견고한 라이브러리를 작성하거나 사용하지 않으면 C에서 문자열 및 목록 조작이 지루하고 오류가 발생하기 쉽습니다. C++과 다른 모든 언어가 왜 발명되었는지 알 수 있습니다.

관련 문제