prosource

NULL 값 또는 정의되지 않은 포인터에 재할당

probook 2023. 6. 17. 09:27
반응형

NULL 값 또는 정의되지 않은 포인터에 재할당

나는 책을 읽다가 거기에 언급된 요점에 대해 혼란스러워 했습니다.아래 코드를 고려하십시오.

#include <stdio.h>
#include <stdlib.h>

int main () {

    int* ptr = NULL;
    ptr = realloc(ptr, 10*sizeof(int));
    return 0;
}

메모리를 할당하는 데 위험이 있습니까?realloc처음에 사용NULL-가치가 있는ptr다음과 같은 경우:

int* ptr = NULL;

나는 이것을 가지고 있었습니다.

int* ptr; // no value given to ptr

전화하는 것이 문제가 될까요?realloc사용.ptr?

초기 NULL 값 ptr을 사용하여 재할당으로 메모리를 할당하는 데 위험이 있습니까?

없음.

7.22.3.5

ptr이 null 포인터인 경우 재할당 함수는 지정된 크기에 대한 malloc 함수처럼 작동합니다.

두 번째 파트의 경우:

int* ptr; // no value given to ptr

ptr을 사용하여 재할당을 호출하는 것이 문제가 됩니까?

초기화되지 않은 포인터를 사용하는 경우 값을 예측할 수 없기 때문에 매우 심각한 문제입니다.함수realloc에 대해서만 올바르게 작동함NULL또는 에서 얻은 값malloc/realloc.

그렇지 않으면 ptr이 메모리 관리 함수 [...]에서 이전에 반환한 포인터와 일치하지 않으면 동작이 정의되지 않습니다.

표시된 특정 코드를 사용하면 처음에 null 포인터를 사용하는 데 문제가 없습니다.

변수가ptr초기화되지 않음 - 0 또는 NULL로 설정되지 않음 - 다음으로 모든 호출realloc()사용하는 것은 위험합니다. 동작이 정의되지 않고 운이 좋으면 프로그램이 중단되지만 운이 나쁘면 문제가 오래 전에 코드로 실행된 것을 발견하기 어려울 때까지 프로그램이 잠시 작동하는 것처럼 보입니다.

사용하는 것이 더 좋다고 주장하는 사람들이 있습니다.malloc()초기 할당 및realloc()그 후에그 제안에는 정당성이 있습니다. 특히 당신이 아마도 사용하지 않을 것이기 때문입니다.ptr = realloc(ptr, 0);기억을 자유롭게 하기 위해, 비록 그렇게 할 수 있지만 (그래서 당신은 정말 필요하지 않습니다.malloc()또는free()왜냐면realloc()세 가지 작업을 모두 수행할 수 있습니다.그러나 C90 표준은 다음을 요구합니다.realloc(0, new_size)와 동등하게 일하다malloc(new_size)그리고 저는 다르게 작동하는 C 라이브러리를 알지 못합니다. (그러나 일부는 있을 수 있습니다. 저는 대부분 가장 널리 사용되는 C 라이브러리를 몇 개 사용했을 뿐입니다.)


그러나 다음 코드와 같은 일반적인 경우 코드에 미묘한 문제가 있습니다(그러나 초기 null 포인터와는 관련이 없습니다).

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    char    *ptr = NULL;
    size_t   len = 0;
    char     buffer[256];

    while (fgets(buffer, sizeof(buffer), stdin))
    {
        size_t buflen = strlen(buffer) + 1;
        if (buflen > len)
        {
            if ((ptr = realloc(ptr, buflen)) == 0)  // Danger!
                // ... handle memory allocation failure ...
            len = buflen;
        }
        strcpy(ptr, buffer);
        // ... do something with ptr
    }
    free(ptr);
    return 0;
}

무엇이 위험합니까?위험은 두 번째 또는 후속 메모리 할당이 실패하고ptr할당된 메모리에 대한 유일한 포인터입니다. 이전 값을 null로 덮어썼습니다., 즉, 다음사할메당모해없을 사용하여 할당된 메모리를 해제할 수 없습니다.ptr더 이상 메모리 누수가 발생하지 않습니다. (첫 번째 할당의 경우 초기 값은 0이고 덮어쓴 값은 0이며 변경된 내용은 없습니다. 메모리 누수는 없습니다.그것이 루프가 코드에 추가된 이유입니다.

주먹구구식

  • 쓰지 .ptr = realloc(ptr, newsize);

새 값을 테스트할 때까지 별도의 변수에 저장합니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    char    *ptr = NULL;
    size_t   len = 0;
    char     buffer[256];

    while (fgets(buffer, sizeof(buffer), stdin))
    {
        size_t buflen = strlen(buffer) + 1;
        if (buflen > len)
        {
            char *new_ptr = realloc(ptr, buflen);
            if (new_ptr == 0)
                // ... handle memory allocation failure ...
            ptr = new_ptr;
            len = buflen;
        }
        strcpy(ptr, buffer);
        // ... do something with ptr
    }
    free(ptr);
    return 0;
}

이 코드는 할당 실패 시 메모리 누수가 발생하지 않습니다.

보권장사항: 과같변사마십지오시용하수를라는 .newC++ 컴파일러로 컴파일하는 것을 어렵게 만들 것입니다.로 해도 ( 될 C++ 하는 것은 newCC...C++ 컴파일러로 컴파일하는 것을 명시적으로 방지하지 않는 한.

초기 NULL 값 ptr을 사용하여 재할당을 사용하여 메모리를 할당하는 데 위험이 있습니까?

아니요, 그건 마치...malloc.

다음과 같은 경우:

int* ptr = NULL;

나는 이것을 가지고 있었습니다.

int* ptr; // no value given to ptr

ptr을 사용하여 재할당을 호출하는 것이 문제가 됩니까?

네, 문제가 있을 겁니다.한다면realloc이해할 수 없음NULL그것은 그 위치에서 시작하여 메모리를 확장하려고 시도하거나, 또는 시도할 수 있습니다.free그리고.malloc기억의 또 다른 부분.초기화되지 않은 변수는 값을 가질있으므로 가능성이 매우 높으며 값이 아닙니다.realloc만약 당신이 운이 좋다면, 당신의 프로그램은 즉시 중단될 것입니다.

언급URL : https://stackoverflow.com/questions/12134315/realloc-on-null-valued-or-undefined-pointer

반응형