簡體   English   中英

如何使用指針C ++將元素從2D數組復制到1D數組

[英]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值本身 ,然后嘗試對doubleint 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM