programing

나는 C의 malloc()와 calloc()에 대해 매우 혼란스럽습니다.

closeapi 2023. 10. 13. 22:15
반응형

나는 C의 malloc()와 calloc()에 대해 매우 혼란스럽습니다.

저는 항상 자바로 프로그래밍을 해왔기 때문에 이 부분에 대해 매우 혼란스러워하고 있습니다.

자바 I에서는 포인터를 선언합니다.

int[] array

초기화하거나 메모리를 할당합니다.

int[] array = {0,1,0}
int[] array = new int[3]

이제 C에서는 모든 게 너무 혼란스러워요.처음에 나는 그것이 선언하는 것만큼 쉽다고 생각했습니다.

int array[]

초기화 또는 메모리 할당:

int array[] = {0,1,0}
int array[] = malloc(3*sizeof(int))
int array[] = calloc(3,sizeof(int))

제가 틀리지 않는 이상 위의 내용은 모두 동등한 Java-C인 것 맞죠?

그리고 오늘 저는 다음과 같은 코드를 발견했습니다.

pthread_t tid[MAX_OPS];

그리고 아래의 몇 줄은 초기화도 없이...

pthread_create(&tid[0],NULL,mou_usuari,(void *) 0);

놀랍게도 (적어도 나에게는) 그 코드가 작동합니다!적어도 자바에서는 멋진 Null Pointer를 돌려줄 것입니다.예외"!

그래서 순서대로:

  1. 자바-C의 모든 "번역"에 대한 제 말이 맞나요?

  2. 그 코드는 왜 작동합니까?

  3. 를 하는 것과 ?malloc(n*sizeof(int))그리고.calloc(n,sizeof(int))?

미리 감사드립니다.

배열에 메모리를 할당할 수 없습니다.어레이는 전체 수명 동안 고정된 크기를 가집니다.배열은 null일 수 없습니다.배열이 포인터가 아닙니다.

malloc주소를 프로그램용으로 예약된 메모리 블록으로 반환합니다.메모리 블록을 배열에 "할당"할 수는 없지만 이 메모리 블록의 주소를 포인터에 저장할 수 있습니다. 다행히 배열 구독은 포인터를 통해 정의되므로 "배열과 같은 포인터를 사용"할 수 있습니다.

int *ptr = malloc(5 * sizeof *ptr);
ptr[2] = 5; // access the third element "of ptr"
free(ptr); // always free at the end

크기가 없는 배열을 선언할 때(즉, 크기가 없는 배열을 선언할 때).array[]즉, 에서 결정됨을 즉, 합니다.

int array[] = {1, 2, 3, 4, 5}; // is equal to
int array[5] = {1, 2, 3, 4, 5};

크기가 없고 이니셜라이저가 없는 배열을 선언하려고 하면 오류가 발생합니다.


pthread_t tid[MAX_OPS];이름이 지정된 배열을 선언합니다.tidpthread_tMAX_OPS.

배열에 자동 저장(즉, 선언이 함수 내부에 있고 정적이지 않으며 전역적이지 않은 경우)이 있는 경우 각 배열 요소는 불확정한 값을 가지게 되며, 이는 그러한 값을 읽으려는 정의되지 않은 동작을 야기합니다.다행히 함수 호출은 배열의 첫 번째 요소의 주소를 첫 번째 매개 변수로 사용하여 함수 내부에서 (요소) 초기화하는 것입니다.


의 차이.calloc그리고.malloc 블록입니다.calloc반환은 0으로 초기화됩니다.즉;

int *ptr = calloc(5, sizeof *ptr);
// is somewhat equal to
int *ptr = malloc(5 * sizeof *ptr);
memset(ptr, 0, 5 * sizeof *ptr);

사이의 차이

int *ptr = malloc(5 * sizeof *ptr);
// and
int array[5];

array는 자동 저장, (스택에 저장되며) 범위를 벗어난 후 "해제"됩니다.ptr되며, (됨), 이어야 .free프로그래머에 의해 d.

세 가지 기본적인 것을 놓쳤기 때문에 (그리고 오해의 소지가 있습니다!)C 항목:

  • 배열과 포인터의 차이
  • 정적 할당과 동적 할당의 차이
  • 스택 또는 힙에 변수를 선언하는 것과 다른 점

을 쓰시면.int array[] = malloc(3*sizeof(int));컴파일 오류가 발생합니다('식별자'와 같은 경우 배열 초기화에는 곱슬곱슬한 괄호가 필요합니다).

즉, 배열을 선언하면 정적 초기화만 허용됩니다.

  • int array[] = {1,2,3};스택에 3개의 연속 정수를 저장합니다.
  • int array[3] = {1,2,3};한.것것.
  • int array[3];스택에 3개의 연속 정수를 여전히 예약하지만 초기화하지는 않습니다(컨텐츠는 랜덤 가비지가 됩니다).
  • int array[4] = {1,2,3}; 목록이 하지 않을 이 는 0됩니다를 얻을 수 C99§6.7.8/19). 이 경우 1,2,3,0을 얻을 수 있습니다.

이 모든 경우에 새 메모리를 할당하는 것이 아니라 스택에 이미 커밋된 메모리를 사용하는 것입니다.스택이 꽉 찬 경우에만 문제가 발생합니다(스택 오버플로가 될 것이라고 추측합니다).이러한 이유로 다음과 같이 선언합니다.int array[];틀리고 무의미할 겁니다

사용방법malloc다를(를) 선언해야 합니다.int* array.

을 쓸 때.int* array = malloc(3*sizeof(int));실제로 세 가지 작업을 수행하고 있습니다.

  1. int* array컴파일러에게 스택의 포인터(메모리 주소를 포함하는 정수 변수)를 예약하도록 지시합니다.
  2. malloc(3*sizeof(int))된 정수를 하나의 3합니다의 합니다.
  3. =된 첫 정수의 을 변수소)합니다에 합니다.

자, 다시 질문으로 돌아오겠습니다.

pthread_t tid[MAX_OPS];

가 없습니다( 는인 ).MAX_OPS예를 들어, 16이면 스택에서 16 pthread_t)에 맞는 데 필요한 연속 바이트 수가 예약됩니다.가 되겠지만,지가 0음)만,pthread_create 변수의 값합니다(에 포인터)을 반환합니다.pthread_t 및 없습니다e)다.

C는 정적 메모리 할당뿐만 아니라 동적 메모리 할당도 제공합니다. 스택에서 벗어나거나 컴파일러가 관리하는 실행 가능한 메모리에서 어레이를 할당할 수 있습니다.이것은 자바에서 스택에 int를 할당하거나 힙에 integer를 할당할 수 있는 방법과 동일합니다.C의 배열은 다른 스택 변수와 마찬가지로 범위를 벗어납니다.C99에서는 크기를 조정할 수 없지만 가변적인 크기를 가질 수도 있습니다.

{}과(와) malloc/calloc의 주요 차이점은 {} 어레이가 사용자를 위해 정적으로 할당되고(사용할 필요가 없음) 자동으로 초기화되는 반면 malloc/calloc 어레이는 명시적으로 사용할 수 있어야 하므로 이러한 어레이를 명시적으로 초기화해야 한다는 것입니다.그러나 물론 malloc/calloc 어레이는 범위를 벗어나는 것이 아니므로 재할당(때로는)할 수 있습니다.

2 - 이 배열 선언은 정적입니다.

pthread_t tid[MAX_OPS];

동적 할당 대신 메모리 블록을 할당할 필요가 없습니다.

pthread_t *tid = (pthread_t *)malloc( MAX_OPS * sizeof(pthread_t) );

기억을 풀어주는 것을 잊지 마세요.

free(tid);

3 - malloc과 calloc의 차이점은 calloc가 배열에 메모리 블록을 할당하고 모든 비트를 0에서 초기화하는 것입니다.

*array를 명시적으로 나타내도록 C로 프로그래밍할 때(C++가 아닌), 이동할 수 있는 포인터가 있다는 것을 기억하는 것이 도움이 됩니다.그래서 먼저 여러분의 예를 다음과 같이 바꾸어 말씀드리겠습니다.

int array[] = {0,1,2};
int *array = malloc(3*sizeof(int));
int *array = calloc(3,sizeof(int));

첫 번째는 0, 1, 2를 포함하는 메모리 블록을 가리키는 array라는 것이 있다는 것입니다. array는 다른 곳으로 이동할 수 없습니다.

다음 코드: pthread_ttid[MAX_OPS];

실제로 (pthread_t) * MAX_OPS 크기의 배열이 할당됩니다.그러나 *tid라는 포인터는 할당하지 않습니다.배열의 기본 주소가 있지만 다른 곳으로 이동할 수는 없습니다.

ptherad_t 타입은 사실상 포인터를 위한 커버입니다.tid위는 실제로 포인터들의 배열입니다.그리고 모두 정적으로 할당되지만 초기화되지는 않습니다.

pthread_create 시작 다()&tid[0].),이며, pthread 합니다.포인터가 새 데이터 구조를 가리키도록 설정되고 데이터 구조가 할당됩니다.

은 -- 은 -- 입니다.malloc(n*sizeof(int))그리고.calloc(n,sizeof(int))가 각 입니다로 입니다.0 에.

언급URL : https://stackoverflow.com/questions/4237896/im-very-confused-about-malloc-and-calloc-on-c

반응형