2012-11-18 3 views
2

off_t 값을 malloc() (예상 값 size_t)으로 전달할 때 문제가 발생할 수 있습니까?모든 파일 내용을 문자열로 읽는 중 - offset_t 값을 malloc()에 전달하는 데 문제가있을 수 있습니까?

나는 파일을 읽고 그 내용을 메모리에 저장하고 있습니다. stat() 함수에 전달 내가 전화를 할 것입니다 경우 다음 메모리가 nmemb 나의 malloc()buf로 파일 크기를 반환 통과 fread()malloc()에 전달 된 후 파일 크기는 struct stat에서 st_size 구성원에 의해 얻어진다.

그러나 질문은 : 파일 크기가 실제로 size_t에 의해 보유 될 수없는 큰 수인 경우 malloc()의 32 비트/64 비트 시스템에서의 작동은 무엇인가 : 정수 오버플로 및 깨진 buf 요청한 바이트 수가 실제로 반환되지 않았습니다) 또는 NULL?

나는 정말로 일어날 수는 없다는 것을 알고 있기 때문에 아마도이 응용 프로그램을 슈퍼 컴퓨터에 사용하고 내 파서에게 가장 큰 파일을 요청할 것입니다. 그러나 나는 행동에 대해서 가능한 한 최대의 것을 이해하는 것을 정말로 좋아합니다. 그건 결코 일어날 수없는 일입니다.

답변

1

파일 크기가 어느 정도 될 것으로 예상됩니까? 보통에서 큰 파일 (MiB는 몇 개 있지만 2 GiB 미만)에서는 문제가 없습니다. 파일이 2 GiB보다 크고 32 비트 시스템을 사용하는 경우 모든 종류의 문제가 발생합니다. 파일이 2 GiB보다 크지 만 64 비트 (Unix) 시스템에있는 경우 문제는 주로 스레 싱을 피하기 위해 실제 메모리를 사용할 수 있습니다. 관계없이 mmap()을 사용해보십시오.

하지만 파일 크기가 실제로 size_t가 보유 할 수없는 큰 숫자 인 경우 32 비트/64 비트 컴퓨터에서 malloc() 함수의 동작은 무엇입니까?

off_t의 값이 size_t에서 개최 할 수있는 범위보다 큰 경우, 다음 malloc() 것 '작업 (32 비트 시스템에 완벽하게 그럴듯 윈도우 64가 아닌 64 비트 시스템에 대한 믿기 어려운) '이지만, off_t 값의 하위 비트에 필요한 공간을 할당합니다. 이것은 당신이 의도 한 것이 아닙니다. 구체적이고 그러나 그럴듯한 예 : off_t이 64 비트 수량이지만 size_t이 32 비트 수량 인 경우 의 하위 비트는 malloc()의 크기로 사용되며 상위 비트는 무시됩니다. 상위 비트가 모두 0이면 문제가되지 않습니다. 상위 비트 중 하나가 설정되면 할당되지 않은 메모리를 남용합니다.

malloc()은 문제를 감지 할 수 없습니다. <stdlib.h>의 선언에 올바른 유형이 나와 있기 때문에 컴파일러에서 size_t이 제공됩니다. 컴파일러가 잘라내기를 경고하는지 여부가 중요합니다. 가능한 문제에 대해 경고 할 의무는 없습니다.

큰 파일 크기에서는 사용하는 형식의 제한을 알고 있어야하며 예상 한 결과를 얻는 지 확인하는 데 매우주의해야합니다 (요청한 결과 대신에, 반드시 같은 것은 아닙니다).

1

문제가 있습니다. 먼저 파일 크기를 읽으려고하면 사용자가 본질적으로 파일 크기를 읽지 못하게됩니다. 파이프. 파일의 데이터에 무작위로 액세스해야합니까? 그렇지 않으면 스트림 지향 방식으로 파일을 구문 분석하십시오.메모리에 절대적으로 필요하다면 stat을 사용하여 파일 크기가 off_t으로 수용 할 수있는 것보다 큰지 먼저 확인할 수 있습니다. 파일 크기가 stat 구조체에 맞지 않으면 은 errno==EOVERFLOW으로 실패합니다. size_t (st_size ~ SIZE_MAX 또는 ((size_t)-1))을 수용하고 조기에 보석금을 받으십시오 (RAM에 읽는 경우에도 프로세스가 포인터를 처리하기에 충분한 비트 수를 가지지 못합니다). 그 외에도 malloc을 시도하십시오 NULL 반환 값) 또는 아마도 mmap (사용 가능한 경우) 파일 일 수 있습니다. 이 비표준이기 때문에


POST의 SCRIPTUM

@R (즉, 비 POSIX.) 기술적으로 현실에 stat64가 쉽게 사용할 수 있지만, 매우 정확 (나 stat64을 언급 좋아하지 않았다 Solaris, OSX, HP-UX, AIX, QNX 및 Windows의 MSVCRT에서도 문서화되어 있습니다. OpenBSD에서는 stat에 이미 large file support이 있기 때문에 은 OpenBSD에서 사용 가능한이 아닙니다.

>을 2 기가 바이트 파일 크기를 검색하는 기존의 (그리고 다소 standard) 방법은 sizeof(off_t) >= 64/8 여부를 확인하기 위해 당신은 아직도이 것 (stat없이 행동 stat64처럼 만들 수도 있습니다 _LARGEFILE_SOURCE, _LARGEFILE64_SOURCE_FILE_OFFSET_BITS=64를 사용하여 구축하는 것입니다 당신이 8TB를 지원하는지 여부를 확실히 알고 있어야합니다.)

사실의 진실은 위의 모든 것이 귀하의 경우 학업에 있다는 것입니다. off_tsize_t 중 작은 크기로 수용 할 수있는 용량을 초과하는 경우에만 초기 체크에 대한 정확한 파일 크기를 알 필요가 없습니다. 그에 따라 원래 답변을 업데이트했습니다.

+0

'stat_t'는 비표준'stat64'가 아니라'off_t'가 64 비트 인 적절한 프로그래밍 환경과 함께 사용하십시오. –

+0

@R .., IIRC 당신이 "off_t"가 64 비트 인 적절한 프로그래밍 환경으로 "stat"를 호출하는 것은 * 내가 생각할 수있는 대부분의 플랫폼에서 실제로'stat64'이다 (Linux, Solaris 등, 아마도 ABI/compatibility * oblige *와 같은) 전 처리기 설탕 (OpenBSD는 아닐지도 모르겠다.) 위의 검사의 요점은 "올바른 일을하는 것"이다. 아무 것도하지 않으면 서 누군가가 올바른 LFS 매크로를 정의하는 것을 잊었 기 때문에 컴파일 시간,'stat64'를 위해 곧바로갔습니다. 그렇지만'sizeof (off_t)> = 64'를 확인하고 지원한다면 LFS 활성화에 대해 경고 할 수 있습니다. – vladr

+0

저의 요점은 당신이 구현 세부 사항 (예 :'stat64' 또는'mmap2', 후자는 함수 이름조차도 내부 syscall 이름이 아닙니다)을 깨끗하고 이식 가능한 프로그래밍 관행 대신에 가르쳐서는 안된다는 것입니다. –