Ні, ви не виділяєте пам'ять 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. Я ніколи не зрозумію, чому кожен відчуває потребу в цьому. :(