Проблема с массивом динамичных массивов
`#include <iostream>
using namespace std;
void PrintDiagonalArray(int** f, int n, int k) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i - j == k) {
cout << f[i][j] << " ";
}
}
}
}
void printArray(int** f, int n) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cout << f[i][j] << "\t";
}
cout << "\n";
}
}
void fillArray(int** f, int n) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
f[i][j] = i + j;
}
}
}
int main() {
const int n = 10;
int* b = new int[n];
int** bb = new int* [n];
for (int i = 0; i < n; i++) bb[i] = b + i * n;
fillArray(bb, n);
printArray(bb, n);
delete bb;
delete b;
}
` Проблема в том, что он ведет себя неопределенно, то заполняет все как надо, при втором запуске, вообще ничего не выводит, в некоторых адресах может хранится мусор.
Ответы (1 шт):
Вы пытаетесь заполнить квадратную матрицу n*n (10 * 10 = 100) элементов.
В строке int* b = new int[n]; вы выделили место по 10 элементов.
Далее, выражение b + i * n, для i>0, будет указывать на область за пределами выделенного массива. После это выражение попадет в fillArray, где по нему будет совершена запись данных - это неопределенное поведение (UB). Далее программа имеет право делать что угодно.
Есть два пути исправления, в зависимости от ого хотите ли вы хранить данные одним блоком, или отдельными блоками для каждой строки.
- С-путь: код будет потенциально быстрее
int* b = new int[n * n]; /// и далее никаких изменений
- С++ - путь: код будет более гибким к последующим изменениям, поскольку будет понятно, кто является владельцем данных для каждого конкретного указателя, включая указатели в массиве bb.
int main() {
const int n = 10;
//int* b = new int[n];
int** bb = new int* [n];
for (int i = 0; i < n; i++) bb[i] = new int[n];
fillArray(bb, n);
printArray(bb, n);
for (int i = 0; i < n; i++) delete bb[i];
delete bb;
//delete b;
}
