Я определяю динамический массив в c++:
double *values;
int size = 5;
values = new (nothrow) double[size];
Я знаю, что это работает, потому что оно компилируется, но я вижу некоторые потенциальные проблемы.
Скажем, я хочу присвоить значения этому массиву:
double samples = [1,2,3,4,5,6];
values = samples; //runtime error: free or corruption
Что именно происходит для генерации этой ошибки?
Вы должны использовать std::copy
для копирования статического массива в динамический массив, как показано ниже:
#include <iostream>
#include <algorithm>
int main() {
int *a = new int[5];
int b[] = {1, 2, 3, 4, 5};
std::copy(b, b + 5, a);
for(std::size_t i(0); i < 5; ++i) std::cout << a[i] << " ";
std::cout << std::endl;
return 0;
}
Альтернативно, если вы хотите удобство назначений вместо элементарного копирования и при условии, что вы знаете размер массивов во время компиляции, а ваш компилятор поддерживает функции С++ 11, используйте std::array
как показано ниже:
#include <iostream>
#include <array>
int main() {
std::array<int, 5> a;
std::array<int, 5> b {{1, 2, 3, 4, 5}};
a = b;
for(auto i : a) std::cout << i << " ";
std::cout << std::endl;
return 0;
}
Тем не менее, рекомендуется использовать std::vector
для использования необработанных динамических массивов, как показано ниже:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> a(5);
int b[] = {1, 2, 3, 4, 5};
std::copy(b, b + 5, a.begin());
for(auto i : a) std::cout << i << " ";
std::cout << std::endl;
return 0;
}
Это не работает, потому что вы назначаете статический массив указателю.
double *values;
double samples[] = {1,2,3,4,5,6};
Это два разных типа данных в отношении компилятора.
Когда ты говоришь:
values = new double[size];
Вы создаете блок кучи (динамической) памяти, а "значения" содержат адрес памяти первого элемента в массиве. Чтобы заполнить значения из вашего статического массива, вам необходимо отдельно назначить каждый элемент следующим образом:
values[0] = samples[0];
values[1] = samples[1];
// or better yet
for (int i = 0; i < size; i++)
values[i] = samples[i]
new double[size]
, вы создаете утечки памяти и переполнения буфера.
Вы можете использовать std::vector
который имеет конструктор итератора, это решит проблему для вас.
std::vector<double> values(std::begin(samples), std::end(samples));
Это обеспечит правильную очистку памяти кучи, даже в случае исключения, и использует механизмы отладки реализации, чтобы защитить вас от таких событий, как переполнение буфера.
double samples[] = {1,2,3,4,5,6};