getline() vs. fgets(): 메모리 할당 제어
파일에서 줄을 읽으려면 다음과 같습니다.getline()
그리고.fgets()
의 POSIX능 시)gets()
라는 것이 상식입니다.getline()
보다 선호합니다.fgets()
필요에 따라 라인 버퍼를 할당하기 때문입니다.
제 질문은 위험하지 않나요?실수로 또는 악의적인 의도로 100GB 파일을 생성하는 경우'\n'
바이트를 입력합니다 – 그러면 제가getline()
미친 양의 메모리를 할당할 수 있습니까?
제 질문은 위험하지 않나요?실수로 또는 악의적인 의도로 '\n' 바이트가 없는 100GB 파일을 만든 경우에는 어떻게 해야 합니까? 그러면 getline() 호출에 엄청난 양의 메모리가 할당되지 않습니까?
네, 말씀하신 것은 그럴듯한 위험입니다.하지만,
- 프로그램이 한 번에 전체 라인을 메모리에 로드해야 하는 경우, 허용합니다.
getline()
그것을 시도하는 것은 본질적으로 그것을 하기 위해 당신 자신의 코드를 쓰는 것보다 더 위험하지 않습니다.fgets()
; 그리고 - 만약 당신이 그러한 취약점을 가지고 있는 프로그램을 가지고 있다면, 당신은 다음을 사용함으로써 위험을 줄일 수 있습니다.
setrlimit()
예약할 수 있는 (가상) 메모리의 총 양을 제한합니다.이를 사용하면 시스템의 나머지 부분을 방해할 만큼 충분한 메모리를 성공적으로 할당하는 대신 장애가 발생할 수 있습니다.
전반적으로 가장 좋은 것은 입력이 필요 없는 코드를 (한 번에) 전체 줄 단위로 작성하는 것이지만, 그러한 접근법은 고유한 복잡성을 가지고 있습니다.
위험할 수도 있습니다.다른 컴퓨터에서는 어떻게 작동할지 모르지만 아래 코드를 실행하면 컴퓨터가 하드 리셋이 필요할 정도로 얼어붙었습니다.
/* DANGEROUS CODE */
#include <stdio.h>
int main(void)
{
FILE *f;
char *s;
size_t n = 0;
f = fopen("/dev/zero", "r");
getline(&s, &n, f);
return 0;
}
MISRAC와 같은 코딩 지침은 동적 메모리 할당을 사용하는 것을 방해할 수 있습니다(예:getline()
예를 들어 메모리 누수를 피할 수 있는 이유가 있습니다.
모든 허용 가능한 라인의 최대 크기를 알고 있다면 다음을 사용하여 메모리 할당을 피할 수 있습니다.fgets()
대신에getline()
, 메모리 누출 가능성이 있는 한 지점을 제거합니다.
getline
함수 용도malloc
그리고.realloc
내부적으로 실패할 경우 -1을 반환하므로 결과는 호출을 시도한 경우와 다르지 않습니다.malloc(100000000000)
. ,errno
설정됩니다.ENOMEM
그리고.getline
-1을 반환합니다.
그래서 당신이 사용하던지 같은 문제가 생길 것입니다.getline
같은 일을 하려고 했거나fgets
수동 메모리 할당을 통해 전체 라인을 읽을 수 있습니다.
실제로 너무 긴 줄을 어떻게 처리할지에 따라 달라집니다.
fgets
적당한 크기의 버퍼는 일반적으로 작동하며 버퍼 끝에 새 줄 문자가 없는 "failed"가 있음을 감지할 수 있습니다.버퍼가 오버플로되었는지 확인하기 위해 항상 strlen()을 수행하는 것을 피할 수 있지만, 이는 다른 질문입니다.
처리할 수 없는 대사를 그냥 생략하는 것이 전략일 수도 있고, 아니면 나머지 대사는 어쨌든 무시할 수 있는 코멘트일 수도 있습니다. 그런 경우에는 쉽게 넣을 수 있습니다.fgets
나머지 라인을 폐기하기 위해 할당 패널티가 없는 루프를 사용합니다.
상관없이 전체 라인을 읽고 싶다면,getline
당신에게 더 좋은 전략일지도 모릅니다.악의적인 사용자는 사용자가 설명한 잘못된 동작을 유발하거나 입력 파일 이름과 유사한 /dev/random을 전달하기 위해 많은 디스크 공간이 필요합니다.
다시 한번, 만약getline
재할당할 수 없습니다. 여러 줄 읽기에 버퍼를 재사용하는 경우 오류가 발생한 후 버퍼가 여전히 할당되어 있고 오류가 발생하기 전에 최대 크기로 커졌을 수 있기 때문에 버퍼를 더 읽기 전에 해제해야 할 수도 있습니다.
getline()
버퍼를 재할당하여 프로그램의 메모리 관리를 조금이나마 완화할 수 있습니다.
하지만 실제로 이로 인해 메모리가 많이 할당될 수 있습니다.문제가 있다면 메모리를 암시적으로 할당하지 않는 함수를 사용하기 위해 추가적인 조치를 취해야 합니다.
언급URL : https://stackoverflow.com/questions/55970169/getline-vs-fgets-control-memory-allocation
'programing' 카테고리의 다른 글
동적양식명속성동적양식명속성동적양식명속성Angularjs Angularjs Angularjs (0) | 2023.10.24 |
---|---|
AngularJS - 지시 크기에 바인딩 (0) | 2023.10.24 |
SELECT 결과에서 긴 텍스트 필드 길이 제한 (0) | 2023.10.24 |
우커머스 체크아웃에서 '라벨 띄우기'를 할 수 있는 방법이 있습니까?(Shopify처럼) (0) | 2023.10.24 |
활성화 버튼 대신 HTML 양식의 Enter 키를 제출하도록 만들기 (0) | 2023.10.24 |