繁体   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