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에 메모리를 할당하면서 메모리 낭비로 보입니다. 컴파일러가 실제로하는 일과 y와 y-> x를 모두 초기화하는 올바른 방법이 무엇인지 알려 주시면 대단히 감사하겠습니다.
미리 감사드립니다.
아니요, 메모리를 두 번 할당 하지 않습니다y->x .
대신 (포인터 포함) 구조에 대한 메모리를 할당하고 플러스 를 차례로 그 포인터를 위해 무언가를.
다음과 같이 생각하십시오.
1 2
+-----+ +------+
y------>| x------>| *x |
| n | +------+
+-----+
따라서 실제로 모든 것을 저장 하려면 두 개의 할당 ( 1및 2)이 필요합니다 .
추가적으로, 당신의 타입은 struct Vector *y포인터이기 때문에 절대로 mallocC 에서 반환 값을 캐스트해서는 안됩니다. 숨기고 싶지 않은 특정 문제를 숨길 수 있기 때문입니다. 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);
}
}
By encapsulating the creation like that, you ensure that vectors are either fully built or not built at all - there's no chance of them being half-built. It also allows you to totally change the underlying data structures in future without affecting clients (for example, if you wanted to make them sparse arrays to trade off space for speed).
The first time around, you allocate memory for Vector, which means the variables x,n.
However x doesn't yet point to anything useful.
So that is why second allocation is needed as well.
Few points
struct Vector y = (struct Vector*)malloc(sizeof(struct Vector)); is wrong
it should be struct Vector *y = (struct Vector*)malloc(sizeof(struct Vector)); since y holds pointer to struct Vector.
1st malloc() only allocates memory enough to hold Vector structure (which is pointer to double + int)
2nd malloc() actually allocate memory to hold 10 double.
You could actually do this in a single malloc by allocating for the Vector and the array at the same time. Eg:
struct Vector y = (struct Vector*)malloc(sizeof(struct Vector) + 10*sizeof(double));
y->x = (double*)((char*)y + sizeof(struct Vector));
y->n = 10;
This allocates Vector 'y', then makes y->x point to the extra allocated data immediate after the Vector struct (but in the same memory block).
If resizing the vector is required, you should do it with the two allocations as recommended. The internal y->x array would then be able to be resized while keeping the vector struct 'y' intact.
In principle you're doing it correct already. For what you want you do need two malloc()s.
Just some comments:
struct Vector y = (struct Vector*)malloc(sizeof(struct Vector));
y->x = (double*)malloc(10*sizeof(double));
should be
struct Vector *y = malloc(sizeof *y); /* Note the pointer */
y->x = calloc(10, sizeof *y->x);
In the first line, you allocate memory for a Vector object. malloc() returns a pointer to the allocated memory, so y must be a Vector pointer. In the second line you allocate memory for an array of 10 doubles.
In C you don't need the explicit casts, and writing sizeof *y instead of sizeof(struct Vector) is better for type safety, and besides, it saves on typing.
You can rearrange your struct and do a single malloc() like so:
struct Vector{
int n;
double x[];
};
struct Vector *y = malloc(sizeof *y + 10 * sizeof(double));
When you allocate memory for struct Vector you just allocate memory for pointer x, i.e. for space, where its value, which contains address, will be placed. So such way you do not allocate memory for the block, on which y.x will reference.
First malloc allocates memory for struct, including memory for x (pointer to double). Second malloc allocates memory for double value wtich x points to.
참고URL : https://stackoverflow.com/questions/14768230/malloc-for-struct-and-pointer-in-c
'IT Share you' 카테고리의 다른 글
| math.h를 포함 했음에도 불구하고 C에서 pow ()에 대한 정의되지 않은 참조 (0) | 2020.11.10 |
|---|---|
| data.frame의 두 열 사이에 열 추가 (삽입) (0) | 2020.11.10 |
| Bootstrap 3의 글 리피 콘을 흰색으로 변경하려면 어떻게합니까? (0) | 2020.11.10 |
| ': app : compileDebugAidl'작업에 대한 실행 실패 : aidl이 없습니다. (0) | 2020.11.10 |
| react-router로 페이지를 떠나는 사용자 감지 (0) | 2020.11.10 |