簡體   English   中英

如何在 C 中返回具有動態多維 arrays 的結構?

[英]How do I return a struct with dynamic multidimensional arrays in C?

我有以下問題:“如果我嘗試返回一個帶有動態多維數組的結構,我會丟失該數組內的數據。如果我使用指針返回該結構,我會遇到同樣的問題。在某些情況下,我有一些位置在具有預期數據的數組中”-> 如何返回包含動態多維數組的結構? -> 我的錯誤在哪里?

這是一個顯示問題的示例程序:

#include <stdio.h>
#include <stdlib.h>

struct just_a_structure
        {
         double **lf_multi_array;
         float   *f_array;
        };

struct just_a_structure get_struct(int i_length)
    {
     struct just_a_structure return_this_struct;
     return_this_struct.lf_multi_array  = (double**)malloc(i_length*sizeof(double*));
     return_this_struct.f_array         = (float*)malloc(i_length*sizeof(float*));

     double lf_dummy_0[10] = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9};
     double lf_dummy_1[10] = {1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9};

     return_this_struct.lf_multi_array[0] = lf_dummy_0;
     return_this_struct.f_array[0]       = 0.00;

     return_this_struct.lf_multi_array[1] = lf_dummy_1;
     return_this_struct.f_array[1]       = 0.01;    
    
     printf("\n output in function \n");
     printf("ma[0][0] %f \n", return_this_struct.lf_multi_array[0][0]);
     printf("ma[0][1] %f \n", return_this_struct.lf_multi_array[0][1]);
     printf("ma[0][2] %f \n", return_this_struct.lf_multi_array[0][2]);
     printf("ma[0][3] %f \n", return_this_struct.lf_multi_array[0][3]);
     printf("ma[0][4] %f \n", return_this_struct.lf_multi_array[0][4]);
     printf("ma[0][5] %f \n", return_this_struct.lf_multi_array[0][5]);
     printf("ma[0][6] %f \n", return_this_struct.lf_multi_array[0][6]);
     printf("ma[0][7] %f \n", return_this_struct.lf_multi_array[0][7]);
     printf("ma[0][8] %f \n", return_this_struct.lf_multi_array[0][8]);
     printf("ma[0][9] %f \n", return_this_struct.lf_multi_array[0][9]);
     printf("a[0] %f \n", return_this_struct.f_array[0]);
     
     printf("\n \n");
     printf("ma[1][0] %f \n", return_this_struct.lf_multi_array[1][0]);
     printf("ma[1][1] %f \n", return_this_struct.lf_multi_array[1][1]);
     printf("ma[1][2] %f \n", return_this_struct.lf_multi_array[1][2]);
     printf("ma[1][3] %f \n", return_this_struct.lf_multi_array[1][3]);
     printf("ma[1][4] %f \n", return_this_struct.lf_multi_array[1][4]);
     printf("ma[1][5] %f \n", return_this_struct.lf_multi_array[1][5]);
     printf("ma[1][6] %f \n", return_this_struct.lf_multi_array[1][6]); 
     printf("ma[1][7] %f \n", return_this_struct.lf_multi_array[1][7]); 
     printf("ma[1][8] %f \n", return_this_struct.lf_multi_array[1][8]); 
     printf("ma[1][9] %f \n", return_this_struct.lf_multi_array[1][9]);
     printf("a[1] %f \n", return_this_struct.f_array[1]);
    
     return return_this_struct;
    }
    
    
int main()
    {    
     int i_length = 500;
     
     struct just_a_structure returned_struct;
    
     returned_struct = get_struct(i_length);
    
     printf("\n output in main \n");
     printf("ma[0][0] %f \n", returned_struct.lf_multi_array[0][0]);
     printf("ma[0][1] %f \n", returned_struct.lf_multi_array[0][1]);
     printf("ma[0][2] %f \n", returned_struct.lf_multi_array[0][2]);
     printf("ma[0][3] %f \n", returned_struct.lf_multi_array[0][3]);
     printf("ma[0][4] %f \n", returned_struct.lf_multi_array[0][4]);
     printf("ma[0][5] %f \n", returned_struct.lf_multi_array[0][5]);
     printf("ma[0][6] %f \n", returned_struct.lf_multi_array[0][6]);
     printf("ma[0][7] %f \n", returned_struct.lf_multi_array[0][7]);
     printf("ma[0][8] %f \n", returned_struct.lf_multi_array[0][8]);
     printf("ma[0][9] %f \n", returned_struct.lf_multi_array[0][9]);
     printf("a[0] %f \n", returned_struct.f_array[0]);
     
     printf("\n \n");
     printf("ma[1][0] %f \n", returned_struct.lf_multi_array[1][0]);
     printf("ma[1][1] %f \n", returned_struct.lf_multi_array[1][1]);
     printf("ma[1][2] %f \n", returned_struct.lf_multi_array[1][2]);
     printf("ma[1][3] %f \n", returned_struct.lf_multi_array[1][3]);
     printf("ma[1][4] %f \n", returned_struct.lf_multi_array[1][4]);
     printf("ma[1][5] %f \n", returned_struct.lf_multi_array[1][5]);
     printf("ma[1][6] %f \n", returned_struct.lf_multi_array[1][6]); 
     printf("ma[1][7] %f \n", returned_struct.lf_multi_array[1][7]); 
     printf("ma[1][8] %f \n", returned_struct.lf_multi_array[1][8]); 
     printf("ma[1][9] %f \n", returned_struct.lf_multi_array[1][9]);
     printf("a[1] %f \n", returned_struct.f_array[1]);

     return 0;
    }

這是程序的output:

 output in function
ma[0][0] 0.000000
ma[0][1] 0.100000
ma[0][2] 0.200000
ma[0][3] 0.300000
ma[0][4] 0.400000
ma[0][5] 0.500000
ma[0][6] 0.600000
ma[0][7] 0.700000
ma[0][8] 0.800000
ma[0][9] 0.900000
a[0] 0.000000


ma[1][0] 1.000000
ma[1][1] 1.100000
ma[1][2] 1.200000
ma[1][3] 1.300000
ma[1][4] 1.400000
ma[1][5] 1.500000
ma[1][6] 1.600000
ma[1][7] 1.700000
ma[1][8] 1.800000
ma[1][9] 1.900000
a[1] 0.010000

 output in main
ma[0][0] 27471811305989270000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
ma[0][1] 27471811305989273000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
ma[0][2] 24361411570075108000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
ma[0][3] 22932960320429427000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
ma[0][4] 0.000000
ma[0][5] 0.000000
ma[0][6] 23754367043167420000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
ma[0][7] 27471811305989273000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
ma[0][8] -519591837366427200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000 
ma[0][9] 0.000000
a[0] 0.000000


ma[1][0] 21266032917854245000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
ma[1][1] 21427427439475540000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
ma[1][2] 0.000000
ma[1][3] 0.000000
ma[1][4] 0.000000
ma[1][5] 0.000000
ma[1][6] 22334679298120726000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
ma[1][7] -1.#QNAN0
ma[1][8] 23669996832223273000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
ma[1][9] 0.000000
a[1] 0.010000

我試圖實現@Etini 和@Sourav Ghost 提供的解決方案。 但是要知道程序在啟動后會立即崩潰。

     return_this_struct.lf_multi_array[0] = (double*)malloc(10*sizeof(double));
     return_this_struct.lf_multi_array[1] = (double*)malloc(10*sizeof(double));
     return_this_struct.f_array           = (float*)malloc(i_length*sizeof(float*));

     double lf_dummy_0[10] = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9};
     double lf_dummy_1[10] = {1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9};
     
     for(int i = 0; i < 10; i++)
        {
         return_this_struct.lf_multi_array[0][i] = lf_dummy_0[i];
        }
     for(int i = 0; i < 10; i++)
        {
         return_this_struct.lf_multi_array[1][i] = lf_dummy_1[i];
        }
        
     return_this_struct.f_array[0]       = 0.00;
     return_this_struct.f_array[1]       = 0.01;    
    ```

在您的代碼中

return_this_struct.lf_multi_array[0] = lf_dummy_0;

return_this_struct.lf_multi_array[1] = lf_dummy_1;

both are storing the address of a local variable in the pointer, hence once returned from the called function, these local variables go out of scope and you're accessing invalid memory, creating undefined behaviour.

如果要返回值,請為數組分配 memory,並復制單個元素值。

正如 Sourav Ghost 所說,您需要分配和復制單個元素,這就是我使它適用於第一個數組的方式

 return_this_struct.lf_multi_array[0] = (double*) malloc(10*sizeof(double));
     for(int i = 0; i < 10; i++){
         return_this_struct.lf_multi_array[0][i] = lf_dummy_0[i];
     }

我的 C 生銹了,請耐心等待。

這兩行正在創建一個堆棧 memory,退出 function 時將刪除該堆棧:

double lf_dummy_0[10] = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9};
double lf_dummy_1[10] = {1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9};

這兩行並沒有將存儲在lf_dummy_0lf_dummy_0中的值復制到您的 multi_array 中。

return_this_struct.lf_multi_array[0] = lf_dummy_0;
...
return_this_struct.lf_multi_array[1] = lf_dummy_1;

現在,我們將您的問題分解成幾部分怎么樣?

首先,讓我們編寫一個返回單個值數組的方法,並確保在 function 結束后可以訪問這些值。

#include <stdio.h>
#include <stdlib.h>

double *getPointerToArrayWithValues(int capacity){
    double * array = (double *) malloc(sizeof(double) * capacity);    

    double value = 0.0;
    for (int i = 0; i < capacity; ++i){
        array[i] = value;
        value += 0.1;
    }
    
    return array;
}

int main()
{
    int size = 10;
    double * array = getPointerToArrayWithValues(size);
    for (int i = 0; i < size; ++i){
        printf("arra[%d]: %f\n", i, array[i]);
    }
    free(array);
    return 0;
}

您可能會注意到,在我獲取值並顯示它們之后,我正在釋放我們使用的 memory。 我們必須自己清潔。

還注意到我使用的是雙精度而不是浮點數。 原因是它比混合浮點和雙精度更容易使用。

其次,讓我們看看我們是否可以創建一個數組或 arrays aka。 多陣列。

#include <stdio.h>
#include <stdlib.h>

double **getPointerToMultiArrayWithValues(int rowCapacity, int columnCapacity){
    // Add space for rows
    double ** multiArray = (double **) malloc(sizeof(double * ) * rowCapacity);
     
    // Add space for columns
    for(int i = 0; i < rowCapacity; ++i){
        multiArray[i] = (double *) malloc(sizeof(double *) * columnCapacity);   
    }
    
    double value = 0.0;
    for (int row = 0; row < rowCapacity; ++row){
        for (int column = 0; column < columnCapacity; ++column){
            multiArray[row][column] = value;
            value += 0.1;
        }
    }
    
    return multiArray;
}

int main()
{
    int numberOfArrayToHold = 10;
    int sizeOfEachArray = 10;
    double ** multiArray = getPointerToMultiArrayWithValues(numberOfArrayToHold, sizeOfEachArray);
    
    for(int i = 0; i < numberOfArrayToHold; ++i){
        for (int j = 0; j < sizeOfEachArray; ++j){
            printf("multiArray[%d][%d]: %f\n", i, j, multiArray[i][j]);
        }
    }

    // Lets be grown up and clean after ourselves
    for (int i = 0; i < numberOfArrayToHold; ++i){
        free(multiArray[i]);
    }
    free(multiArray);

    return 0;
}

現在,您已經解決了如何創建單數組和多數組(在本例中為雙數組),我們可以專注於創建一個包含此類數組的結構:

#include <stdio.h>
#include <stdlib.h>

struct ArrayHolder{
  int rows;
  int columns;
  double ** multiArray;
};

double **getPointerToMultiArrayWithValues(int rowCapacity, int columnCapacity){
    // Add space for rows
    double ** multiArray = (double **) malloc(sizeof(double * ) * rowCapacity);
     
    // Add space for columns
    for(int i = 0; i < rowCapacity; ++i){
        multiArray[i] = (double *) malloc(sizeof(double *) * columnCapacity);   
    }
    
    double value = 0.0;
    for (int row = 0; row < rowCapacity; ++row){
        for (int column = 0; column < columnCapacity; ++column){
            multiArray[row][column] = value;
            value += 0.1;
        }
    }
    
    return multiArray;
}

int main()
{
    struct ArrayHolder arrayHolder;
    arrayHolder.rows = 10;
    arrayHolder.columns = 10;
    arrayHolder.multiArray = getPointerToMultiArrayWithValues(arrayHolder.rows, arrayHolder.columns);
    
    for(int i = 0; i < arrayHolder.rows; ++i){
        for (int j = 0; j < arrayHolder.columns; ++j){
            printf("multiArray[%d][%d]: %f\n", i, j,  arrayHolder.multiArray[i][j]);
        }
    }
    
    for (int i = 0; i < arrayHolder.rows; ++i){
        free(arrayHolder.multiArray[i]);
    }
    free( arrayHolder.multiArray);

    return 0;
}

但是,我們希望返回一個結構,不是嗎? 然后,

#include <stdio.h>
#include <stdlib.h>

struct ArrayHolder{
  int rows;
  int columns;
  double ** multiArray;
};

double **getPointerToMultiArrayWithValues(int rowCapacity, int columnCapacity){
    // Add space for rows
    double ** multiArray = (double **) malloc(sizeof(double * ) * rowCapacity);
     
    // Add space for columns
    for(int i = 0; i < rowCapacity; ++i){
        multiArray[i] = (double *) malloc(sizeof(double *) * columnCapacity);   
    }
    
    double value = 0.0;
    for (int row = 0; row < rowCapacity; ++row){
        for (int column = 0; column < columnCapacity; ++column){
            multiArray[row][column] = value;
            value += 0.1;
        }
    }
    
    return multiArray;
}

struct ArrayHolder getStructWithArray(){
    struct ArrayHolder arrayHolder;
    arrayHolder.rows = 10;
    arrayHolder.columns = 10;
    arrayHolder.multiArray = getPointerToMultiArrayWithValues(arrayHolder.rows, arrayHolder.columns);
    return arrayHolder;
}

int main()
{
   
    struct ArrayHolder arrayHolder = getStructWithArray(); 
    for(int i = 0; i < arrayHolder.rows; ++i){
        for (int j = 0; j < arrayHolder.columns; ++j){
            printf("multiArray[%d][%d]: %f\n", i, j,  arrayHolder.multiArray[i][j]);
        }
    }
    
    for (int i = 0; i < arrayHolder.rows; ++i){
        free(arrayHolder.multiArray[i]);
    }
    free( arrayHolder.multiArray);

    return 0;
}

在這種情況下,我們按值返回結構(已復制)

但是,我們也可以通過指針來完成!

#include <stdio.h>
#include <stdlib.h>

struct ArrayHolder{
  int rows;
  int columns;
  double ** multiArray;
};

double **getPointerToMultiArrayWithValues(int rowCapacity, int columnCapacity){
    // Add space for rows
    double ** multiArray = (double **) malloc(sizeof(double * ) * rowCapacity);
     
    // Add space for columns
    for(int i = 0; i < rowCapacity; ++i){
        multiArray[i] = (double *) malloc(sizeof(double *) * columnCapacity);   
    }
    
    double value = 0.0;
    for (int row = 0; row < rowCapacity; ++row){
        for (int column = 0; column < columnCapacity; ++column){
            multiArray[row][column] = value;
            value += 0.1;
        }
    }
    
    return multiArray;
}

struct ArrayHolder * getPointerToStructWithArray(){
    struct ArrayHolder* arrayHolder = (struct ArrayHolder *) malloc(sizeof(struct ArrayHolder));
    arrayHolder -> rows = 10;
    arrayHolder -> columns = 10;
    arrayHolder -> multiArray = getPointerToMultiArrayWithValues(arrayHolder -> rows, arrayHolder -> columns);
    return arrayHolder;
}

int main()
{
   
    struct ArrayHolder * arrayHolder = getPointerToStructWithArray(); 
    for(int i = 0; i < arrayHolder -> rows; ++i){
        for (int j = 0; j < arrayHolder -> columns; ++j){
            printf("multiArray[%d][%d]: %f\n", i, j,  arrayHolder -> multiArray[i][j]);
        }
    }
    
    for (int i = 0; i < arrayHolder -> rows; ++i){
        free(arrayHolder -> multiArray[i]);
    }
    free( arrayHolder -> multiArray);
    
    free(arrayHolder);

    return 0;
}

讓我知道這是否對您有所幫助。

在使用循環分配值之前,您必須像這樣分配數組return_this_struct.lf_multi_array[0] = (double*) malloc(10*sizeof(double));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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