it-source

C에서 메모리를 동적으로 할당해야 하는 이유는 무엇입니까?

criticalcode 2023. 10. 13. 22:17
반응형

C에서 메모리를 동적으로 할당해야 하는 이유는 무엇입니까?

동적 메모리 할당은 C 프로그래밍에서 매우 중요한 주제입니다.하지만 저는 이것이 우리가 무엇을 할 수 있게 하는지, 또는 왜 그것이 필요한지에 대한 좋은 설명을 찾을 수 없었습니다.

변수와 구조를 선언하고 malloc()을 절대 사용할 필요가 없는 것은 아닌가요?

참고 사항으로 다음과 같은 차이점은 무엇입니까?

ptr_one = (int *)malloc(sizeof(int));

그리고.

int *ptr_one = malloc(sizeof(int));

다음과 같은 경우 동적 메모리를 사용해야 합니다.

  • 컴파일 시 사용할 최대 메모리 양을 결정할 수 없습니다.
  • 매우 큰 개체를 할당하려고 합니다.
  • 상한 크기가 고정되지 않은 데이터 구조(컨테이너)를 구축하려고 합니다.

컴파일할 때 어느 정도의 메모리를 확보해야 하는지 항상 알 수 있는 것은 아닙니다.파일의 레코드 수가 고정되어 있지 않은 데이터 파일(온도의 시계열)을 처리하는 것을 상상해 보십시오.적게는 10장, 많게는 10만 장까지 소장할 수 있습니다.해당 데이터를 처리하기 위해 메모리로 모든 데이터를 읽으려면 파일을 읽기 전에는 할당할 메모리 양을 알 수 없습니다.첫 번째 값이 레코드 수가 되도록 파일을 구성하는 경우 다음과 같은 작업을 수행할 수 있습니다.

size_t recs = 0;
double *temps = NULL;

FILE *fp = fopen ( filename, "r" );
if ( fp )
{
  if ( fscanf( fp, "%zu", &recs ) == 1 )
  {
    temps = malloc( sizeof *temps * recs );
    if ( temps )
    {
      // read contents of file into temps
    }
  }
}

때때로 당신은 매우 물체를 할당할 필요가 있습니다. 예를 들면,

int ginormous[1000][1000][1000];

4바이트 정수를 가정하면 이 배열에는 4GB가 필요합니다.불행히도 스택 프레임(대부분의 아키텍처에서 로컬 변수가 유지됨)은 그보다 훨씬 작은 경향이 있으므로 그만큼의 메모리를 할당하려고 하면 런타임 오류가 발생할 수 있습니다(일반적으로 그렇습니다).동적 메모리 풀(일명 히프)은 일반적으로 스택보다 훨씬 크며, 스택 프레임은 훨씬 작습니다.그러니까 그렇게 불쾌한 일을 하려면 당신은 다음과 같은 글을 써야 할 것입니다.

int (*ginormous)[1000][1000] = malloc( sizeof *ginormous * 1000 );

이와 같은 요청이 실패할 수도 있습니다. 힙이 충분히 조각화되어 있으면 요청을 처리할 수 있을 만큼 큰 연속 블록이 하나도 없을 수도 있습니다.필요한 경우 개별적으로 할당할 수 있습니다. 행이 반드시 메모리에 인접하지는 않지만 필요한 모든 메모리를 확보할 수 있을 가능성이 높습니다.

int ***ginormous = malloc( sizeof *ginormous * 1000 );
if ( ginormous )
{
  for ( size_t i = 0; i < 1000; i++ )
  {
    ginormous[i] = malloc( sizeof *ginormous[i] * 1000 );
    if ( ginormous[i] )
    {
      ginormous[i][j] = malloc ( sizeof *ginormous[i][j] * 1000 );
      if ( ginormous[i][j] )
      {
        // initialize ginormous[i][j][k]
      }
    }
  }
}

마지막으로 동적 메모리를 사용하면 목록, 트리, 큐 등과 같이 데이터를 추가하거나 제거할 때 확장 및 축소할 수 있는 컨테이너를 구축할 수 있습니다.제 다"링과 에 따라 할 수 "" 데이터할 수도 .stringC++)를 입력합니다.

메모리에 대한 최악의 요구 사항을 모를 때는 동적 할당이 필요합니다.그러면 얼마나 필요할지 모르기 때문에 필요한 메모리를 정적으로 할당하는 것은 불가능합니다.

최악의 경우 요구 사항을 알고 있더라도 동적 메모리 할당을 사용하는 것이 바람직할 수 있습니다.이를 통해 시스템 메모리를 여러 프로세스에서 보다 효율적으로 사용할 수 있습니다.모든 프로세스는 최악의 경우 메모리 요구 사항을 정적으로 처리할 수 있지만, 이는 시스템에 실행 중인 프로세스의 수를 제한합니다.모든 프로세스가 최악의 경우를 동시에 사용하지 않는 경우 시스템 메모리의 사용률이 계속 낮아지므로 리소스 낭비가 됩니다.

에게 를 걸어 본.malloc()C. 이것은 누락된 선언의 버그를 숨길 수 있으며(암시적 선언은 C.99 이전에 허용됨), 정의되지 않은 동작을 초래합니다.합니다의 것을 합니다.malloc()깁스를 하지 않고malloc()합니다를(를) 반환할 합니다.void * C , 의 변환.void *그리고 됩니다(modulo 다)와 같은 modulo ).const).

으로 입니까의 ptr_one = (int *)malloc(sizeof(int))그리고.int *ptr_one = malloc(sizeof(int))

이거 봐요.

첫째, 동적 메모리 할당은 C 프로그래밍에서 매우 중요한 주제이기 때문에 이것이 우스꽝스러운 질문일 가능성이 높다는 것을 알고 있습니다.하지만 저는 이것이 우리가 무엇을 할 수 있게 하는지, 또는 왜 그것이 필요한지에 대한 좋은 설명을 찾을 수 없었습니다.

메모리 풀(또는 일반적으로 힙)은 스택에 비해 매우 큽니다.스택을 통해 메모리 풀을 사용하는 것이 유용한 이유에 대해 다음 두 가지 예를 생각해 보십시오.

1.어레이를 정의하고 여러 스택 프레임 간에 지속되도록 하려면 어떻게 해야 합니까?물론 글로벌 변수로 선언할 수도 있고 메모리의 글로벌 데이터 섹션에 저장될 것입니다. 하지만 프로그램이 점점 커질수록 이 문제는 더 복잡해질 것입니다.또는 메모리 풀에 저장할 수도 있습니다.

int *func( int k ) {
  assert( k >= 1 );

  int *ptr_block = malloc( sizeof( int ) * k );

  if ( ptr_block == NULL ) exit( EXIT_FAILURE );

  for ( int i = 0; i < k; i++ ) {
    ptr_block[ i ] = i + 1;
  }

  return ptr_block; // Valid.
}

... 그러나 스택에 배열을 정의한 경우에는 작동하지 않습니다.이유는 스택 프레임이 터지면 모든 메모리 주소는 다른 스택 프레임에서 사용될 수 있지만(따라서 덮어쓰기), 메모리 풀의 메모리를 사용하는 것은 다음과 같이 유지됩니다.free사용자(사용자 또는 클라이언트)가 d.

2.임의의 큰 수열을 읽는 것을 처리하기 위해 동적 배열을 구현하고자 한다면 어떨까요?스택에서 배열을 정의할 수 없습니다. 메모리 풀을 사용해야 합니다.구조물에 포인터를 전달하는 것은 매우 일반적이며(구조물을 복사해야 하는 경우가 아니라면 매우 권장됨), 구조물 자체는 절대로 크지 않습니다.동적 어레이의 소규모 구현을 예로 들 수 있습니다.

struct dyn_array {
  int *arr;
  int len;
  int cap;
};

typedef struct dyn_array *DynArray;

void insert_item( int const item, DynArray dyn_arr ) {
  // Checks pre conditions.
  assert( dyn_arr != NULL );

  // Checks if the capacity is equal to the length. If so, double.
  if ( dyn_arr->cap == dyn_arr->len ) {
    dyn_arr->cap *= 2;

    DynArray new_dyn_arr = malloc( sizeof( int ) * dyn_arr->cap ); // [oo]

    // ... copy, switch pointers and free...
  }

  // ... insert, increase length, etc.
}

...온라인.[oo]스택에 정의된 경우, 이 스택 프레임이 터지면 어레이의 모든 메모리 주소가 더 이상 할당되지 않습니다.즉, 다른 스택 프레임(다음 스택 프레임)은 해당 메모리 주소(또는 일부 하위 집합)를 사용하게 됩니다.

비고: 내 코드 조각에서,ptr_block스택에 저장됩니다. 따라서&ptr_block는 스택 주소입니다. 그러나 값은ptr_block메모리 풀에서 어딘가에 있습니다.

언급URL : https://stackoverflow.com/questions/18217525/why-or-when-do-you-need-to-dynamically-allocate-memory-in-c

반응형