Это не современный C ++, и, очевидно, вам не следует удалять возвращаемое значение.
я пытаюсь скопировать значения из строки row_num двумерного массива the_array
в 1D массив
Во-первых, the_array
в этом контексте, определяемый как необработанный указатель и используемый для арифметики указателей, представляет собой одномерное представление двумерного массива - лучше быть точным в нашем описании.
ошибка, которую я получаю [...]: операнд '*' должен быть указателем
Хорошо, вот эта строка:
*row = *(*(the_array + row_num) + i);
это беспорядок. Я думаю, я вижу, куда вы шли с этим, но посмотрите, вы разыменовываете (используя *
слева от выражения) дважды без причины, что BTW вызывает Ошибка. Помните, что мы сказали, что the_array
- это необработанный указатель , который рассматривается как одномерный массив. Следовательно, вы можете использовать этот тип арифметики с указателями, скажем, внутри скобок, а затем разыменовать его только один раз. Ваше выражение выше берет результирующий адрес (the_array + row_num)
, разыменовывает его, чтобы получить double
в пределах этой ячейки массива, а затем добавляет i
к самому значению double
и затем пытается разыменуйте эту сумму double
и int i
- которая является временной переменной типа double
, а не указателем. Это, вероятно, линия, к которой вы стремились:
*row = *(the_array + row_num * col_size + i);
Поскольку двумерные данные заразно распространяются в памяти, строка за строкой, последовательно , вам необходимо умножить индекс строки, подобный этому, на размер строки (который также является числом столбцов, и Я полагаю, что col_size
на самом деле так, иначе у вас нет возможности перемещаться между строками), чтобы «пропустить между строками» и, наконец, добавить индекс текущей ячейки i
, чтобы добраться до конкретной ячейки внутри строки , Затем, как мы уже говорили, разыменовываем все это.
Помимо расчета проблемы компиляции и адреса, вы должны по крайней мере сохранить адрес row
, прежде чем увеличивать его в цикле, чтобы вы могли возвращать его, а не указатель за концом строки. В максимально возможной степени сохраняя исходную функцию, вы можете сделать это с помощью второго указателя , например:
double* get_row(double *the_array, int row_num, int col_size) {
double* row = new double[col_size];
double* rowPtr = row;
for (int i = 0; i < col_size; i++) {
*rowPtr = *(the_array + row_num * col_size + i);
rowPtr++;
}
return row;
}
Я стараюсь сделать это как можно ближе к вашей версии, чтобы вы могли увидеть разницу с тем, что вы сделали. Многие вещи лучше сделать по-другому, например, , почему бы сначала не использовать оператор []
, такой как row[i] = *(the_array + row_num * col_size + i);
, а затем вообще избавиться от второго указателя? Нет реальной необходимости делать ++
там в качестве второй строки цикла, если вы перебираете i
как есть. Другой пример: Вы должны были выделить или просто вернуть указатель на существующий массив , но в нужном месте?
Слишком важно не упомянуть здесь, что почти в любом сценарии вам действительно не следует возвращать необработанный указатель , как это, поскольку это может слишком легко привести к неясным намерениям в коде относительно того, кто владеет распределением (и в конечном итоге отвечает за его удаление) и ставит вопрос о том, как предотвратить утечку памяти в случае исключения? Предпочтительным решением является использование интеллектуальных указателей, , таких как std::unique_ptr
, экземпляр которого оборачивает необработанный указатель и делает его таким, что вам придется быть очень явным, если вы захотите просто бросить этот кусок памяти небезопасным способом.