Null 종단 문자열
Null-terminated string컴퓨터 프로그래밍에서 늘 종단 문자열은 문자를 포함하는 배열로 저장되며 늘 문자(이 문서에서는 값이 0인 문자, NUL이라고 부릅니다)로 끝나는 문자열입니다.C 문자열은 C 프로그래밍 언어와 ASCIIZ를 나타냅니다(단[citation needed], C는 ASCII 이외의 인코딩을 사용할 수 있습니다).
문자열의 길이는 (첫 번째) NUL을 검색하여 구할 수 있습니다.이것은 문자열 길이에 대해 O(n)(선형 시간)가 걸리기 때문에 느릴 수 있습니다.또한 문자열에 NUL을 포함할 수 없음을 의미합니다(메모리에는 NUL이 있지만 문자열의 "in"이 아니라 마지막 문자 뒤에 있습니다).
역사
Null 종단 문자열이 에 의해 생성되었습니다..ASCIZ
PDP-11 어셈블리의 언어 및 명령어ASCIZ
PDP-10용 매크로 어셈블리 언어의 디렉티브입니다.이것들은 C 프로그래밍 언어의 개발보다 앞서 있지만, 다른 형태의 문자열이 자주 사용되었습니다.
C(및 C에서 파생된 언어)가 개발되었을 때 메모리는 매우 제한적이었기 때문에 문자열의 길이를 저장하기 위해 오버헤드를 1바이트만 사용하는 것이 매력적이었습니다.일반적으로 "Pascal string"(더 현대적인 용어는 "length-prefixed")이라고 불리는 그 당시에 유일하게 인기 있었던 대체 용어는 문자열의 길이를 저장하기 위해 선행 바이트를 사용했습니다.이를 통해 문자열에 NUL을 포함할 수 있고 이미 저장된 문자열의 길이를 검색할 수 있습니다.메모리 액세스(O(1)(정수) 시간)는 1개뿐이지만 문자열 길이는 255자로 제한됩니다(8비트바이트를 사용하는 머신에서는).C 디자이너 Dennis Ritchie는 끈의 길이에 대한 제한을 피하기 위해 null-termination의 관례를 따르기로 선택했고, 그의 경험상 카운트를 유지하는 것이 [1][2]터미네이터를 사용하는 것보다 덜 편리해 보였기 때문이다.
이는 CPU 명령 세트 설계에 어느 정도 영향을 미쳤습니다.1970년대와 1980년대의 일부 CPU(Zilog Z80 및 DEC VAX 등)에는 길이 프리픽스된 문자열을 처리하기 위한 전용 명령이 있었습니다.그러나 null 종단 문자열이 설득력을 얻으면서 CPU 설계자들은 이를 고려하기 시작했습니다. 예를 들어 1992년 "논리 문자열 지원" 명령을 ES/9000 520에 추가하고 2015년 [3]벡터 문자열 명령을 IBM z13에 추가하기로 한 IBM의 결정에서 볼 수 있습니다.
FreeBSD 개발자인 Poul-Henning Kamp는 ACM 큐에 기술되어 있으며, 늘 종단 문자열이 2바이트(1바이트가 아님) 길이에 대해 "[4]가장 비싼 1바이트 실수"라고 언급하고 있습니다.
제한 사항
이 표현은 구현이 간단하지만 오류 및 성능 문제가 발생하기 쉽습니다.
Null-termination으로 인해 보안 문제가 [5]발생하였습니다.문자열 중간에 NUL이 삽입되면 NUL이 예기치 않게 [6]잘립니다.일반적인 오류는 NUL에 추가 공간을 할당하지 않는 것이었기 때문에 인접 메모리에 쓰여졌습니다.다른 하나는 NUL을 전혀 쓰지 않는 것입니다.메모리 블록에 이미 제로가 포함되어 있기 때문에 테스트 중에 NUL이 검출되지 않는 경우가 많습니다.길이를 찾는 데 비용이 많이 들기 때문에 많은 프로그램이 문자열을 고정 크기의 버퍼에 복사하기 전에 신경 쓰지 않고 너무 길면 버퍼 오버플로를 유발했습니다.
0을 저장할 수 없는 경우 텍스트 및 이진 데이터를 구별하여 서로 다른 함수로 처리해야 합니다(후자는 데이터 길이도 제공해야 함).이로 인해 잘못된 기능이 사용될 경우 코드 용장성과 오류가 발생할 수 있습니다.
길이를 찾는 속도 문제는 일반적으로 길이를 O(n)인 다른 연산과 결합함으로써 완화될 수 있습니다. 예를 들어 다음과 같습니다.strlcpy
그러나 이것이 항상 직관적인 API가 되는 것은 아닙니다.
문자 부호화
늘 종단 문자열에서는 부호화가 제로바이트(0x00)를 사용하지 않아야 합니다.따라서 가능한 모든 ASCII [7][8][9]또는 UTF-8 문자열을 저장할 수 없습니다.다만, ASCII 또는 UTF-8 의 서브셋(NUL 를 제외한 모든 문자)은, 늘 종단 문자열에 격납하는 것이 일반적입니다.일부 시스템에서는 NUL을 2개의 비제로 바이트(0xC0, 0x80)로 인코딩하여 가능한 모든 문자열을 저장할 수 있는 "수정 UTF-8"을 사용합니다.이것은 UTF-8 규격에서는 허용되지 않습니다.이는 과도한 부호화이며 보안 위험으로 간주되기 때문입니다.UTF-8에서는 사용되지 않는0xFE 나 0xFF 등, 그 외의 바이트를 스트링의 말미로서 대신 사용할 수 있습니다.
UTF-16은 2바이트의 정수를 사용하며, 어느 쪽 바이트가 제로일 수 있으므로(실제로 ASCII 텍스트를 나타낼 때는 다른 바이트가 모두) 늘 종단 바이트 문자열에 저장할 수 없습니다.단, 일부 언어에서는 16비트 NUL(0x0000)로 끝나는 16비트 UTF-16 문자의 스트링이 구현되어 있습니다.
개선점
C 문자열 처리를 에러 발생을 줄이기 위한 많은 시도가 이루어지고 있습니다.하나의 전략은 다음과 같은 안전한 기능을 추가하는 것입니다.strdup
그리고.strlcpy
다음과 같은 안전하지 않은 기능의 사용을 권장하지 않습니다. gets
또 하나는 C 문자열 주위에 오브젝트 지향 래퍼를 추가하여 안전한 콜만 실행할 수 있도록 하는 것입니다.그러나 안전하지 않은 함수를 호출하는 것은 가능합니다.
대부분의 최신 라이브러리는 C 문자열을 32비트 이상의 길이 값(길이 프리픽스 문자열에 대해 고려된 값보다 훨씬 높음)을 포함하는 구조로 대체하며, 종종 다른 포인터, 참조 수 및 NUL을 추가하여 C 문자열로 변환 속도를 높입니다.메모리 용량이 크게 증가했기 때문에 각 문자열에 3바이트(또는 16바이트 이상)를 추가하는 것이 실제로 문제가 된다면 소프트웨어는 작은 문자열을 너무 많이 처리해야 하므로 다른 스토리지 방식에서는 더 많은 메모리를 절약할 수 있습니다(예를 들어 해시 테이블이 더 적은 메모리를 사용할 수 있습니다).예를 들어 C++ 표준 템플릿 라이브러리가 있습니다. std::string
, Qt QString
, MFC CString
및 C 기반의 실장CFString
핵심 재단과 Objective-C 형제로부터NSString
둘 다 애플이 만든 재단으로부터요.로프와 같은 줄을 저장하기 위해 더 복잡한 구조를 사용할 수도 있습니다.
「 」를 참조해 주세요.
레퍼런스
- ^ Ritchie, Dennis M. (April 1993). The development of the C language. Second History of Programming Languages conference. Cambridge, MA.
- ^ Ritchie, Dennis M. (1996). "The development of the C language". In Bergin, Jr., Thomas J.; Gibson, Jr., Richard G. (eds.). History of Programming Languages (2 ed.). New York: ACM Press. ISBN 0-201-89502-1 – via Addison-Wesley (Reading, Mass).
- ^ IBM z/아키텍처 작동 원리
- ^ Kamp, Poul-Henning (25 July 2011), "The Most Expensive One-byte Mistake", ACM Queue, 9 (7): 40–43, doi:10.1145/2001562.2010365, ISSN 1542-7730, S2CID 30282393
- ^ Rain Forest Puppy (9 September 1999). "Perl CGI problems". Phrack Magazine. artofhacking.com. 9 (55): 7. Retrieved 3 January 2016.
- ^ "Null byte injection on PHP?".
- ^ "UTF-8, a transformation format of ISO 10646". Retrieved 19 September 2013.
- ^ "Unicode/UTF-8-character table". Retrieved 13 September 2013.
- ^ Kuhn, Markus. "UTF-8 and Unicode FAQ". Retrieved 13 September 2013.