memcpy의 이상한 행동

Oct 26 2020

부호없는 긴 정수를 바이트 단위로 char 버퍼에 복사하고 싶습니다. 주석 아래 줄을 사용하면 버퍼에 복사되지 않습니다.

    char buf[128];
    //unsigned long int_val = 268435456;
    unsigned long int_val = 293456376;

    cout << "Value of int_val: " << int_val << endl;

    memset(buf, 0, sizeof(buf));

    memcpy(buf, &int_val, sizeof(long));
    cout << "Value after unsigned long int copy - buf: " << buf << endl;

    const int len = strlen(buf);
    cout << "buf" << endl << "====" << endl;
    for (int i = 0; i < len; i++)
    {
        printf("%3d (0x%02X)\n", buf[i], buf[i]);
    }

다음은 각 값을 사용하여 두 번 실행 한 결과입니다.

Value of int_val: 268435456
Value after unsigned long int copy - buf:
buf
===

Value of int_val: 293456376
Value after unsigned long int copy - buf: ��}
buf
===
 -8 (0xFFFFFFF8)
-55 (0xFFFFFFC9)
125 (0x7D)
 17 (0x11)

답변

4 EricPostpischil Oct 26 2020 at 17:42

16 진수에서 268435456은 10000000 16 입니다. C ++는 unsigned long낮은 값 바이트가있는 메모리에의 바이트를 메모리에 저장하므로 값이 00 16 , 00 16 , 00 16 , 10 16 인 바이트로 메모리에 저장됩니다 .

memcpy이 바이트를 buf.

그런 strlen(buf)다음를 검사 할 때 먼저 buf널 바이트 (00 16 )를 찾습니다 . buf종료 문자가 시작 부분에 즉시 나타나므로의 문자열 길이가 0 임을 나타냅니다 . 따라서 strlen(buf)0을 반환합니다.

이 반환 값이에 할당 len되므로 루프는 for (int i = 0; i < len; i++)0 반복을 수행합니다.

마찬가지로,에서 cout << "Value after unsigned long int copy - buf: " << buf << endl;, buf어떤 문자가 그것을 인쇄되지 않도록, 길이가 0 인 문자열이 포함되어 있습니다.

5 eerorika Oct 26 2020 at 17:31

버퍼에 복사되지 않습니다.

네, 그렇습니다.

cout << ... << buf << endl;
const int len = strlen(buf);

당신이 보는 출력을 기대하지 않은 이유는 분명하지 않습니다. 0은 널 종료 문자의 값입니다. 정수의 최하위 메모리 순서 바이트가 0이면 버퍼에는 빈 문자열을 나타내는 널로 끝나는 문자열이 포함됩니다. 이 경우 표시되는 출력이 예상됩니다. 리틀 엔디안 시스템 (및 long4 바이트보다 넓은 빅 엔디안 시스템 )에서는 16 진수로 0x10'00'00'00 인 268435456의 경우가 발생합니다.

복사 한 바이트가 빈 문자열을 나타 내기 때문에 바이트가 복사되지 않았다는 의미는 아닙니다.