Нет, вы не выделяете память y->x
дважды.
Вместо этого вы выделяете память для структуры (которая включает указатель) плюс что-то, на что указывает этот указатель.
Подумайте об этом так:
1 2
+-----+ +------+
y------>| x------>| *x |
| n | +------+
+-----+
Таким образом, вам действительно нужны два распределения ( 1
и 2
) для хранения всего.
Кроме того, ваш тип должен быть struct Vector *y
указателем, и вы никогда не должны приводить возвращаемое значение из malloc
C, так как это может скрыть определенные проблемы, которые вы не хотите скрывать - C вполне способен неявно преобразовывать void*
возвращаемое значение в любой другой указатель.
И, конечно же, вы, вероятно, захотите инкапсулировать создание этих векторов, чтобы упростить управление ими, например, с помощью:
struct Vector {
double *data;
size_t size;
};
struct Vector *newVector (size_t sz) {
struct Vector *retVal = malloc (sizeof (struct Vector));
if (retVal == NULL)
return NULL;
retVal->data = malloc (sz * sizeof (double));
if (retVal->data == NULL) {
free (retVal);
return NULL;
}
retVal->size = sz;
return retVal;
}
void delVector (struct Vector *vector) {
if (vector != NULL) {
free (vector->data);
free (vector);
}
}
Инкапсулируя создание таким образом, вы гарантируете, что векторы либо полностью построены, либо не построены вообще - нет никаких шансов, что они будут построены наполовину. Это также позволяет полностью изменить базовые структуры данных в будущем, не затрагивая клиентов (например, если вы хотите сделать их разреженными массивами, чтобы сэкономить место на скорости).
malloc()
в C. Я никогда не пойму, почему все чувствуют необходимость в этом. :(