不,你是not分配内存用于y->x
twice.
相反,您为结构分配内存(其中包括指针)plus该指针指向的东西。
可以这样想:
1 2
+-----+ +------+
y------>| x------>| *x |
| n | +------+
+-----+
你实际上需要two分配(1
and 2
)来存储您需要的一切。
此外,您的类型应该是struct Vector *y
因为它是一个指针,所以你不应该将返回值转换为malloc
in C.
它可以隐藏某些您不想隐藏的问题,并且 C 完全能够隐式转换void*
返回值给任何其他指针。
当然,您可能希望封装这些向量的创建,以便更轻松地管理它们,例如在头文件中包含以下内容vector.h
:
struct Vector {
double *data; // Use readable names rather than x/n.
size_t size;
};
struct Vector *newVector(size_t sz);
void delVector(struct Vector *vector);
//void setVectorItem(struct Vector *vector, size_t idx, double val);
//double getVectorItem(struct Vector *vector, size_t idx);
然后,在vector.c
,您拥有管理向量的实际函数:
#include "vector.h"
// Atomically allocate a two-layer object. Either both layers
// are allocated or neither is, simplifying memory checking.
struct Vector *newVector(size_t sz) {
// First, the vector layer.
struct Vector *vector = malloc(sizeof (struct Vector));
if (vector == NULL)
return NULL;
// Then data layer, freeing vector layer if fail.
vector->data = malloc(sz * sizeof (double));
if (vector->data == NULL) {
free(vector);
return NULL;
}
// Here, both layers worked. Set size and return.
vector->size = sz;
return vector;
}
void delVector(struct Vector *vector) {
// Can safely assume vector is NULL or fully built.
if (vector != NULL) {
free(vector->data);
free(vector);
}
}
通过像这样封装向量管理,您可以确保向量要么完全构建,要么根本不构建 - 有no它们有可能是半建成的。
它还允许您将来完全更改底层数据结构而不影响客户端。例如:
- 如果你想让它们成为稀疏数组以牺牲空间和速度。
- 如果您希望数据在更改时保存到持久存储中。
- 如果您希望确保所有向量元素都初始化为零。
- if you wanted to separate the vector size from the vector capacity for efficiency(1).
您还可以根据需要添加更多功能,例如安全设置或获取向量值(请参阅标题中的注释代码)。
For example, you could (as one option) silently ignore setting values outside the valid range and return zero if getting those values. Or you could raise an error of some description, or attempt to automatically expand the vector under the covers(1).
在使用向量方面,一个简单的例子如下(非常基本)main.c
#include "vector.h"
#include <stdio.h>
int main(void) {
Vector myvec = newVector(42);
myvec.data[0] = 2.718281828459;
delVector(myvec);
}
(1) That potential for an expandable vector bears further explanation.
许多向量实现将容量与大小分开。前者是在需要重新分配之前可以使用多少个元素,后者是实际的向量大小(始终
扩展时,您通常希望以不进行太多操作的方式进行扩展,因为这可能是一项昂贵的操作。例如,您可以添加比严格必要的多 5% 的元素,这样,在循环中连续添加一个元素时,就不必为每一项重新分配。