programing

C의 구조체 및 포인터에 대한 malloc

itsource 2022. 8. 7. 17:25
반응형

C의 구조체 및 포인터에 대한 malloc

벡터의 길이와 값을 나타내는 구조를 다음과 같이 정의한다고 가정합니다.

struct Vector{
    double* x;
    int n;
};

이제 벡터 y를 정의하고 해당 벡터에 메모리를 할당한다고 가정합니다.

struct Vector *y = (struct Vector*)malloc(sizeof(struct Vector));

인터넷에서 검색한 결과 x에 메모리를 따로 할당해야 합니다.

y->x = (double*)malloc(10*sizeof(double));

단, 메모리를 y->x에 할당하는 경우는 y에 할당하는 경우와 y->x에 할당하는 경우가 2회 있어 메모리 낭비가 되는 경우가 있습니다.컴파일러의 실제 기능과 y와 y->x를 모두 초기화하는 올바른 방법을 알려주시면 감사하겠습니다.

잘 부탁드립니다.

아니요, 메모리 할당이 아닙니다.y->x

대신에, 메모리(포인터 포함)와 그 포인터가 가리키는 것을 할당하는 것입니다.

이렇게 생각해 보세요.

         1          2
        +-----+    +------+
y------>|  x------>|  *x  |
        |  n  |    +------+
        +-----+

는 두 할당이 두 가지 할당이 필요합니다.1 ★★★★★★★★★★★★★★★★★」2모든 것을 저장합니다.

유형은 '아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 이런struct Vector *y 안 .malloc 않은 수 으로 C를 할 수 .void*하다

물론 이러한 벡터의 작성을 캡슐화하여 다음과 같이 관리를 용이하게 할 수도 있습니다.

struct Vector {
    double *data;    // no place for x and n in readable code :-)
    size_t size;
};

struct Vector *newVector (size_t sz) {
    // Try to allocate vector structure.

    struct Vector *retVal = malloc (sizeof (struct Vector));
    if (retVal == NULL)
        return NULL;

    // Try to allocate vector data, free structure if fail.

    retVal->data = malloc (sz * sizeof (double));
    if (retVal->data == NULL) {
        free (retVal);
        return NULL;
    }

    // Set size and return.

    retVal->size = sz;
    return retVal;
}

void delVector (struct Vector *vector) {
    // Can safely assume vector is NULL or fully built.

    if (vector != NULL) {
        free (vector->data);
        free (vector);
    }
}

이와 같이 생성물을 캡슐화함으로써 벡터가 완전히 구축되거나 전혀 구축되지 않은 상태인지 확인할 수 있습니다. 벡터가 반쯤 구축될 가능성은 없습니다.또한 클라이언트에 영향을 주지 않고 나중에 기본 데이터 구조를 완전히 변경할 수 있습니다(예: 스파스 어레이를 사용하여 공간을 속도와 교환하는 경우).

원칙적으로 당신은 이미 그것을 옳게 하고 있다. 것은 두 입니다.malloc()s.

몇 가지 코멘트:

struct Vector y = (struct Vector*)malloc(sizeof(struct Vector));
y->x = (double*)malloc(10*sizeof(double));

그래야 한다

struct Vector *y = malloc(sizeof *y); /* Note the pointer */
y->x = calloc(10, sizeof *y->x);

첫 번째 줄에서는 벡터 개체에 메모리를 할당합니다. malloc()할당된 메모리로 포인터를 반환하므로 y는 벡터 포인터여야 합니다.두 번째 줄에서는 10개의 배열을 위해 메모리를 할당합니다.

캐스팅이 C에는 명시적 캐스팅이 없습니다.sizeof *ysizeof(struct Vector)활자 안전에도 좋고 타이핑 비용도 절감됩니다.

구조를 재정렬하여 싱글을 수행할 수 있습니다.malloc()다음과 같이 합니다.

struct Vector{    
    int n;
    double x[];
};
struct Vector *y = malloc(sizeof *y + 10 * sizeof(double));

메모리를 할당하는 경우struct Vector포인터에 메모리를 할당하면 됩니다.x(예: 공간의 경우 주소를 포함하는 값이 배치됩니다).따라서 블록에 메모리를 할당하지 않습니다.y.x참조하겠습니다.

첫 번째 malloc는 x용 메모리(포인트 투 더블)를 포함한 구조용 메모리를 할당합니다.두 번째 malloc은 x 포인트의 2배의 값에 메모리를 할당합니다.

첫 번째 메모리 할당은Vector즉, 변수가x,n.

하지만x 아직 쓸만한 건 없어요

그래서번째 할당도 필요합니다.

몇 점

struct Vector y = (struct Vector*)malloc(sizeof(struct Vector));틀렸다

그럴 것 같네요.struct Vector *y = (struct Vector*)malloc(sizeof(struct Vector));부터y에 대한 포인터 보유하다struct Vector.

첫 번째malloc()벡터 구조(double + int에 대한 포인터)를 유지할 수 있는 메모리만 할당합니다.

두 번째malloc()실제로 메모리를 할당하여 10개의 더블 홀드를 유지합니다.

언제malloc(sizeof(struct_name))전체 크기의 구조물에 대해 자동으로 메모리를 할당하므로 내부의 각 요소를 malloc할 필요가 없습니다.

사용하다-fsanitize=address플래그를 사용하여 프로그램 메모리 사용 방법을 확인합니다.

벡터와 어레이를 동시에 할당함으로써 실제로 단일 malloc에서 이 작업을 수행할 수 있습니다.예:

struct Vector y = (struct Vector*)malloc(sizeof(struct Vector) + 10*sizeof(double));
y->x = (double*)((char*)y + sizeof(struct Vector));
y->n = 10;

이것에 의해, 벡터 「y」가 할당되어 Y->x 가 벡터 구조체 직후(같은 메모리 블록내에 있는) 추가 할당 데이터를 포인트 합니다.

벡터 크기를 변경해야 할 경우 권장되는 두 가지 할당으로 수행해야 합니다.그러면 벡터 구조 'y'를 그대로 유지하면서 내부 y->x 어레이의 크기를 조정할 수 있습니다.

언급URL : https://stackoverflow.com/questions/14768230/malloc-for-struct-and-pointer-in-c

반응형