Как правильно использовать массивы в C++: от статических до динамических и std::array
Основные типы массивов в C++
В C++ существует три основных способа работы с массивами, и каждый имеет свои особенности. Давайте разберем их от простого к сложному.
1. Статические массивы (C-style arrays)
Это то, с чем вы столкнулись. Они существуют в C++ еще со времен C и имеют ряд ограничений:
// Правильная инициализация
int arr[5] = {1, 2, 3, 4, 5}; // OK
int arr[] = {1, 2, 3, 4, 5}; // Размер выводится автоматически (5)
// НЕЛЬЗЯ присваивать после объявления
int arr[5];
arr = {1, 2, 3, 4, 5}; // Ошибка!
// НЕЛЬЗЯ копировать
int arr1[5] = {1, 2, 3, 4, 5};
int arr2[5] = arr1; // Ошибка!
Проблема с sizeof в функции:
Когда вы передаете массив в функцию, он "распадается" (decays) в указатель. Поэтому sizeof(arr) внутри функции возвращает размер указателя (8 байт на 64-битной системе), а не размер массива.
// Правильный способ передачи статического массива
void printSum(int arr[], int size) {
int sum = 0;
for(int i = 0; i < size; i++) {
sum += arr[i];
}
cout << sum;
}
// Или с использованием шаблона (сохраняет размер)
template<size_t N>
void printSum(int (&arr)[N]) {
int sum = 0;
for(int i = 0; i < N; i++) {
sum += arr[i];
}
cout << sum;
}
int main() {
int arr[5] = {1, 2, 3, 4, 5};
printSum(arr); // N = 5
}
2. Динамические массивы (new/delete)
Используются, когда размер массива неизвестен на этапе компиляции:
int size;
cout << "Enter size: ";
cin >> size;
int* arr = new int[size]; // Выделяем память в куче
// Заполняем
for(int i = 0; i < size; i++) {
arr[i] = i * 10;
}
// Обязательно освобождаем память!
delete[] arr;
Важно: Каждый new[] требует соответствующего delete[]. Забыли — получите утечку памяти.
3. Современные C++ контейнеры (рекомендуемый способ)
std::array (фиксированный размер, C++11)
#include <array>
std::array<int, 5> arr = {1, 2, 3, 4, 5};
// Можно копировать!
std::array<int, 5> arr2 = arr;
// Знает свой размер
cout << arr.size(); // 5
// Безопасный доступ с проверкой границ
cout << arr.at(10); // Выбросит исключение std::out_of_range
std::vector (динамический размер)
#include <vector>
std::vector<int> vec = {1, 2, 3}; // Размер 3
vec.push_back(4); // Теперь размер 4
vec.push_back(5); // Теперь размер 5
// Передача в функцию (всегда знает свой размер)
void printSum(const std::vector<int>& vec) {
int sum = 0;
for(int val : vec) { // Range-based for loop
sum += val;
}
cout << sum;
}
Когда что использовать?
- std::vector — 90% случаев. Динамический размер, удобный, безопасный.
- std::array — когда размер фиксирован и известен на этапе компиляции (например, матрица 3x3).
- Статические массивы — в legacy коде или при работе с низкоуровневыми API (OpenGL, WinAPI).
- Динамические массивы (new[]) — никогда в современном C++. Всегда используйте std::vector.
Исправленный пример с суммой:
#include <iostream>
#include <vector>
int main() {
// Современный способ
std::vector<int> numbers = {1, 2, 3, 4, 5};
int sum = 0;
for(int num : numbers) {
sum += num;
}
std::cout << "Sum: " << sum << std::endl;
return 0;
}
Запомните главное правило: в современном C++ старайтесь избегать сырых массивов и указателей. Используйте std::vector или std::array — они безопаснее, удобнее и не дают совершить глупых ошибок с памятью.
<<Альтернативный подход: работа с многомерными массивами
Если ваш вопрос касается многомерных массивов (матрицы, таблицы), то здесь тоже есть свои тонкости:
// Статический двумерный массив
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
// Доступ к элементу
cout << matrix[1][2]; // 7
// Использование std::vector для динамической матрицы
std::vector<std::vector<int>> dynamicMatrix(3, std::vector<int>(4, 0));
dynamicMatrix[1][2] = 42;
// Или более эффективный вариант с одномерным вектором
std::vector<int> flatMatrix(3 * 4, 0);
int rows = 3, cols = 4;
flatMatrix[1 * cols + 2] = 42; // Эквивалент [1][2]
Для многомерных массивов также настоятельно рекомендую использовать контейнеры STL. Они избавят вас от головной боли с ручным управлением памятью и обеспечат безопасность типов.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги