메모리를 영점화하기
gcc 4.4.4 C89
나는 단지 대부분의 C 프로그래머들이 메모리를 제로로 만들고 싶을 때 무엇을 하는지 궁금합니다.
예를 들어, 저는 1024바이트의 버퍼를 가지고 있습니다.가끔은 이렇게 하죠.
char buffer[1024] = {0};
그러면 모든 바이트가 0이 됩니다.
하지만 이렇게 선언하고 memset을 사용하면 되나요?
char buffer[1024];
.
.
memset(buffer, 0, sizeof(buffer));
메모리를 제로로 만들어야 하는 진짜 이유가 있습니까?그것을 하지 않음으로써 일어날 수 있는 최악의 상황은 무엇입니까?
일어날 수 있는 최악의 상황?NULL이 종료되지 않은 문자열이나 버퍼의 일부에 인쇄한 후에 오른쪽에 있는 모든 것을 상속하는 정수를 (지각하지 않고) 보게 됩니다.그러나 종료되지 않은 문자열은 버퍼를 초기화한 경우에도 다른 방법으로 발생할 수 있습니다.
편집(댓글에서)세상의 종말은 당신이 무엇을 하고 있느냐에 따라 먼 가능성이기도 합니다.
둘 중 하나는 바람직하지 않습니다. 회피하지 한,으로 할당된 가 작기 한,한.memset()
비교적 싼 사실 대부분의 전화보다 훨씬 저렴합니다로 가는 대부분의 .calloc()
~2k보다 큰 경향이 있는 동적 블록의 경우.
c99 는, 를 수 것 .gcc -std=c99
모든 종류의 스토리지를 사용한다는 것에 동의합니다.
여전히 컴파일러가 많이 때문에 ( c99 ) 에를 합니다.memset()
나는 매우 선호합니다.
char buffer[1024] = { 0 };
이것은 더 짧고, 읽기 쉬우며, 오류가 발생하기 쉽습니다.만 가능합니다.memset
동적으로으로 할당을 합니다.calloc
.
할 때char buffer[1024]
초기화하지 않으면 정의되지 않은 데이터를 얻을 수 있습니다.예를 들어 디버그 모드의 Visual C++는 0xcd로 초기화됩니다.Release 모드에서는 메모리만 할당하고 해당 블록에서 이전에 사용한 것과 상관하지 않습니다.
또한 예제는 런타임 대 컴파일 시간 초기화를 보여줍니다.에 당신의 ㅇchar buffer[1024] = { 0 }
는 전역 또는 정적 선언이며, 초기화된 데이터와 함께 이진의 데이터 세그먼트에 저장되므로 이진 크기가 약 1024바이트 증가합니다(이 경우).정의가 함수에 있는 경우 스택에 저장되고 런타임에 할당되며 바이너리에 저장되지 않습니다.되며 A와다에 해당하는 memcpy()
하기 위해 됩니다.buffer
이것이 어떤 방법이 당신에게 가장 적합한지 결정하는 데 도움이 되기를 바랍니다.
이 경우에는 큰 차이가 없습니다.나는 더좋아요= { 0 }
이상memset
.memset
오류가 발생하기 쉽습니다.
- 그것은 한계를 잘못 이해할 수 있는 기회를 제공합니다.
- 은 에 대한 논쟁을 할 수 를 제공합니다.
memset
(예를 들면memset(buf, sizeof buf, 0)
memset(buf, 0, sizeof buf)
.
으로.= { 0 }
다를 하는 데 더 .struct
처럼 모든 마치 글을 쓴 것처럼 모든 멤버를 효과적으로 초기화합니다.= 0
각각을 초기화합니다.즉, 포인터 구성원은 null 포인터로 초기화되는 것이 보장됩니다(null-bits-zero가 아닐 수 있으며, all-bits-zero는 사용한 경우 얻을 수 있는 것입니다).memset
).
에.= { 0 }
다를에 수 .struct
로써를 이라면, 않을 수도 있습니다,다.memcmp
그들을 비교해 보기 위해서요.
그렇게 하지 않음으로써 발생할 수 있는 최악의 경우 문자별로 데이터를 작성하고 나중에 문자열로 해석하는 것입니다(그리고 null terminator를 작성하지 않았습니다).또는 해당 섹션이 초기화되지 않았다는 것을 깨닫지 못하고 유효한 데이터인 것처럼 읽게 됩니다.기본적으로: 모든 종류의 추악함.
Memset은 문제가 없을 것입니다. (타이포의 크기만 수정해 주신다면 :-"당신의 첫 번째 예보다는 그게 더 명확하다고 생각하기 때문에 더 좋아요.
동적으로 할당된 메모리는 malloc과 memset보다는 calloc을 사용합니다.
초기화하지 않으면 발생할 수 있는 일 중 하나는 민감한 정보가 유출될 위험이 있다는 것입니다.
초기화되지 않은 메모리에는 이전에 해당 메모리를 사용했을 때 민감한 내용이 포함되어 있을 수 있습니다.비밀번호나 암호키 또는 개인 이메일의 일부일 수도 있습니다.나중에 코드가 해당 버퍼나 구조를 어딘가로 전송하거나 디스크에 기록할 수 있으며, 일부만 채웠다면 나머지 코드에는 이전 내용이 여전히 포함되어 있습니다.특정 보안 시스템에서는 주소 공간에 민감한 정보가 포함될 수 있는 경우 버퍼를 영점화해야 합니다.
사용하는 것을 선호합니다.memset
특히 문자열로 작업할 때 메모리 덩어리를 지웁니다.제 문자열 뒤에 null 구분자가 있을 것을 의심하지 않고 알고 싶습니다.네, 당신이 추가할 수 있다는 것을 압니다.\0
각각의 끈의 끝과 몇몇 기능들이 당신을 위해 이것을 해주지만, 나는 이것이 일어났다는 것을 의심하고 싶지 않습니다.
버퍼를 사용할 때 함수가 실패할 수 있으며 버퍼는 변경되지 않습니다.알 수 없는 쓰레기가 든 완충제를 드릴까요, 아니면 아무것도 안 드릴까요?
이 게시물은 수정하기 위해 많이 편집되었습니다.제가 놓친 부분을 지적해주신 타일러 맥헤너리 씨께 많은 감사를 드립니다.
char buffer[1024] = {0};
버퍼의 첫 번째 문자를 null로 설정하고 컴파일러는 초기화되지 않은 모든 문자도 0으로 확장합니다.그런 경우 두 기법의 차이는 컴파일러가 배열 초기화에 더 최적화된 코드를 생성하는지, 아니면 생성된 컴파일된 코드보다 memset이 더 빨리 최적화되는지로 귀결되는 것 같습니다.
이전에 다음과 같이 말했습니다.
char buffer[1024] = {0};
버퍼의 첫 번째 문자를 null로 설정합니다.이 기법은 첫 번째 null을 지난 모든 데이터가 null terminated 문자열을 처리하는 후속 함수에 의해 무시되기 때문에 null terminated 문자열에 대해 일반적으로 사용됩니다.
그것은 사실이 아닙니다.소통을 잘못해서 죄송하고, 수정해주셔서 다시 한번 감사드립니다.
어떻게 쓰느냐에 따라 달라질 수 있습니다: 잠재적으로 어떤 것을 읽기도 전에 그것에 글을 쓸 계획이라면, 왜 신경 쓸 필요가 있습니까?하려면 첫 다로 \0
:
char buffer[1024];
buffer[0] = '\0';
이 있을 수 입니다.memset
하거나 하는 것입니다.{ 0 }
당신의 예처럼 현명한 행동입니다.
또한 memset(버퍼, 0, (버퍼)의 크기)를 사용합니다.
사용하지 않을 경우 사용 중인 버퍼가 완전히 비어 있다는 보장이 없기 때문에 예기치 못한 동작이 발생할 수 있습니다.
malloc 후에 항상 memset을 0으로 설정하는 것은 매우 좋은 연습입니다.
예, stdlib.h에 정의된 calloc () 메서드는 0으로 초기화된 메모리를 할당합니다.
저는 다음 내용에 대해 잘 모릅니다.
char buffer[1024] = {0};
기술.하지만 제가 생각하는 대로 이루어진다고 가정하면 두 가지 기술에는 (잠재적) 차이가 있습니다.
첫 번째는 COMPLIVE 시간에 수행되며 버퍼는 실행 파일의 정적 이미지의 일부가 되므로 로드할 때 0이 됩니다.
후자는 RUN TIME에서 실행됩니다.
첫 번째는 로드 시간 동작이 발생할 수 있습니다.만약 당신이 가지고 있다면:
char buffer[1024];
현대의 하역선은 ...하는 virtually의 짐을 싣는 것이 당연합니다.즉, 파일에 실제 공간이 필요하지 않고, 단순히 프로그램이 로드될 때 블록을 조각하라는 로더의 지시가 될 것입니다.나는 현대의 짐꾼들이 그것이 사실인지 아닌지 말하는 것이 충분히 편하지 않습니다.
그러나 사전 초기화를 수행하는 경우 실행 파일에서 로드해야 합니다.
이 두 가지 모두 소규모로 "실제" 성능에 영향을 미치지 않습니다.그들은 "대규모"로 어떤 것도 가지고 있지 않을 수도 있습니다.여기에 잠재력이 있다고 말하는 것과 두 가지 기술은 사실 상당히 다른 일을 하고 있습니다.
언급URL : https://stackoverflow.com/questions/2884230/zeroing-out-memory
'source' 카테고리의 다른 글
Jquery를 사용하여 CSS 속성이 변경된 경우 이벤트 탐지 (0) | 2023.10.06 |
---|---|
경고: PDO::__construct(): [2002] 해당 파일 또는 디렉토리가 없습니다(unix://tmp/mysql.sock을 통해 연결 시도 중). (0) | 2023.10.06 |
문자열이 NULL 또는 공백이 아닌지 확인합니다. (0) | 2023.10.06 |
malloc에서는 왜 brk를 사용합니까?왜 그냥 mmap을 사용하지 않습니까? (0) | 2023.10.06 |
C99에서 이상한 배열 크기[*]와 [정적]는 얼마입니까? (0) | 2023.10.06 |