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 *y
sizeof(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
'programing' 카테고리의 다른 글
node_modules에서 동적 Vue 이미지 src 바인딩 (0) | 2022.08.07 |
---|---|
String.valueOf()와오브젝트.toString() (0) | 2022.08.07 |
Java의 JDK에 동시 목록이 있습니까? (0) | 2022.08.07 |
v-for 루프에서 li 요소 하나가 클릭된 경우 VueJs가 활성 클래스를 설정함 (0) | 2022.08.07 |
C: 시스템 명령어를 실행하여 출력을 얻으시겠습니까? (0) | 2022.08.07 |