2013-04-08 3 views
0

바이트 배열과 그 크기를 어떻게 표현 하시겠습니까? 첫 번째 2/4 바이트 크기를 나타낼 원시 바이트 배열 (서명되지 않은 문자) 저장할 (주 메모리 또는 파일 내에서) 싶습니다. 그러나 그러한 어레이에서의 작업은 잘 보이지 않습니다.바이트 배열과 크기의 멋진 표현

void func(unsigned char *bytearray) 
{ 
    int size; 
    memcpy(&size, bytearray, sizeof(int)); 
    //rest of operation when we know bytearray size 
} 

어떻게 피할 수 있습니까? 간단한 구조에 대해서 생각해 봅니다 :

그리고 저는 bytearray의 크기와 데이터 부분에 접근했습니다. 그러나 여전히 추한 것처럼 보입니다. 다른 접근법을 추천 해 주시겠습니까?

+1

왜 'std :: vector '가 아닌가요? –

+0

왜냐하면 그다지 효과적이지 않습니다. 예를 들어 파일에 저장하고 싶습니다. – Dejwi

+0

파일에 데이터를 저장하는 방법에 대해 묻고 싶다면 그렇게하십시오. 하지만 귀하의 질문은 C++ 유형으로 표현하는 방법에 관한 것입니다. –

답변

2

"Pascal string"을 효과적으로 다시 발명하고 있습니다. 그러나

b->data = reinterpret_cast<unsigned char*>(&(b->size) + 1); 

은 포인터가 자체를 가리키고 포인터가 덮어 쓰기 때문에 전혀 작동하지 않습니다.

당신은 구조의 마지막 요소에 지정되지 않은 크기의 배열을 사용할 수 있어야합니다 : 당신은, 예를 들어, 쓸 수 있도록 std::vector 달리

struct bytearray 
{ 
    int size; 
    unsigned char data[]; 
}; 

bytearray *b = reinterpret_cast<bytearray*>(::operator new(sizeof (bytearray) + 10)); 
b->size = 10; 

//... 

::operator delete(b); 

이 실제로 함께 크기와 데이터를 저장 한 번의 작업으로 파일에 저장합니다. 그리고 메모리 지역성이 더 좋습니다.

여전히 std::vector이 테스트되었고 많은 유용한 알고리즘이 구현되어 있다는 사실은 매우 매력적입니다.

+0

한 번의 작업으로 이식 할 수는 없습니다. –

+0

int 바이너리 표현이 엔디안 방식에 따라 다릅니 까? 아니면 뭔가 다른 것을 염두에두고 있습니까? – Dejwi

+0

@David : 그렇게하는 코드는 이식성이 있습니다. 결과 파일은 아키텍처에 따라 다르며 ('int'의 크기와 표현에 따라 다르다.), 파일을 동일한 컴퓨터의 동일한 애플리케이션 (예 : 캐시)에 다시로드해야하는 많은 애플리케이션이있다. –

5

달리해야 할 압도적 인 이유가없는 한, 관용적 인 일을하고 std :: vector < 부호없는 문자 >을 사용하십시오.

2

나는 std::vector<unsigned char>을 사용하여 메모리를 관리하고 필요한 기능을 수행 할 시간에 구조를 만들기 위해 iovec을 생성하는 변환 함수를 작성합니다. 단일 시스템 호출에 길이와 데이터를 모두 작성해야하는 경우

iovec make_iovec (std::vector<unsigned char> &v) { 
    iovec iv = { &v[0], v.size() }; 
    return iv; 
} 

, iovec를 사용하여, 당신은 그것을 달성하기 writev 전화를 사용할 수 있습니다.

ssize_t write_vector(int fd, std::vector<unsigned char> &v) { 
    uint32_t len = htonl(v.size()); 
    iovec iv[2] = { { &len, sizeof(uint32_t) }, make_iovec(v) }; 
    return writev(fd, iv, 2); 
} 
관련 문제