[英]How to you copy elements from a 2D array into a 1D array using pointers C++
我有一個功能
double* get_row(double *the_array, int row_num, int col_size)
其中the_array
是2D數組, row_num
是2D數組上我要從中復制值的行號, col_size
是2D數組的列大小。
功能實現
double* get_row(double *the_array, int row_num, int col_size) {
double* row = new double[col_size];
for (int i = 0; i < col_size; i++) {
*row = *(*(the_array + row_num) + i);
row++;
}
delete[] row;
return row;
}
我試圖將值從2D數組the_array
row_num
行復制到1D數組row
但是編譯器在行*row = *(*(the_array + row_num) + i);
上給了我一個錯誤*row = *(*(the_array + row_num) + i);
我曾經將元素從一個數組復制到另一個數組,完成此任務的正確方法是什么。
順便說一句,我從Visual Studio得到的錯誤是:'*'的操作數必須是一個指針。
謝謝您的幫助。
我假設“ col_size”實際上是“列數”,以解決此問題。 並且數據按行優先順序排列。
然后,第N行的開頭位於the_array + row_num*col_size
。
我將從這個輔助函數開始:
inline double* view_row_n( double* array, int row, int num_cols ) {
return array+row*num_cols;
}
然后我寫一個復制緩沖區:
std::unique_ptr<double[]> copy_buffer( double const* in, int count ) {
double* retval = new double[count];
std::memcpy( retval, in, sizeof(double)*count );
return std::unique_ptr<double[]>( retval );
}
現在,我將它們一起使用:
double* get_row( double* the_array, int row_num, int col_size) {
auto retval = copy_buffer( view_row_n( the_array, row_num, col_size), col_size );
return retval.release();
}
並完成它。
我也會更改:
double* get_row( double const* the_array, int row_num, int col_size) {
乃至:
std::unique_ptr<double[]> get_row( double const* the_array, int row_num, int col_size) {
但這超出了您的問題范圍。
如果get_row
不需要您將新內存分配回調用方,則解決方案將是
double* get_row(double *the_array, int row_num, int col_size)
{
return the_array + (row_num * col_size);
}
如果期望調用者將新的內存分配給返回的行,則
double* get_row(double *the_array, int row_num, int col_size)
{
double* row = new double[col_size];
for(int i = 0; i < col_size; i++)
row[i] = *(the_array + (row_num * col_size) + i);
return row;
}
會工作。
在第一個解決方案中,想法是使用row_num * col_size
到達正確的行,然后簡單地返回該地址位置作為結果。 在第二個解決方案中,我們首先聲明一個新行。 然后使用i
索引該行中的每個元素,並從the_array
復制由the_array + (row_num * col_size)
索引的行中的每個元素。
這不是現代的C ++,顯然您不應該刪除自己的返回值。
我試圖將值從2D數組the_array的行row_num復制到1D數組中
首先,在這種情況下, the_array
被定義為原始指針,用於指針運算,是2D數組的1D表示形式-在我們的描述中最好是准確的。
我得到的錯誤是[...]:'*'的操作數必須是一個指針
好的,所以這一行:
*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);
由於2D數據連續不斷地在內存中傳播,因此您需要將行索引乘以行大小(這也是列數),我認為col_size
實際上就是那個,否則無法在行之間遍歷)以“在行之間跳過” ,最后添加當前單元格索引i
以獲取行內的特定單元格。 然后,就像我們說的那樣,取消對整個事物的引用。
除了編譯問題和地址計算之外,您還應至少在循環中增加row
地址之前保留該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);
首先使用[]
運算符row[i] = *(the_array + row_num * col_size + i);
然后完全擺脫第二個指針? 如果您按原樣遍歷i
,則實際上不需要在循環中的第二行進行++
。 另一個例子是您是否必須分配,還是可以在正確的地方返回一個指向現有數組的指針 ?
此處不重要提及的是,在幾乎任何情況下, 您實際上都不應該返回這樣的原始指針 ,因為它很容易導致代碼的意圖不明確,如誰擁有分配(並負責刪除)最終),並提出了在異常情況下如何防止內存泄漏的問題? 首選的解決方案是使用智能指針, 例如std::unique_ptr
,該實例的一個實例包裝原始指針並使之指向原始指針,因此,如果您只想拋出該指針,則必須非常明確內存以不安全的方式存儲。
double* get_row(double *the_array, int row_num, int col_size) {
double* row = new double[col_size];
for (auto i = 0; i < col_size; ++i) {
row[i] = the_array[row_num * col_size + i];
}
// If the return isn't assigned, the program will leak!
return row;
}
void row_test() {
double two_d[15];
const auto row = get_row(two_d, 2, 5);
// ...
// Be sure to delete row afterwards
delete[] row;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.