动态的动态数组(struct数组)

Posted

技术标签:

【中文标题】动态的动态数组(struct数组)【英文标题】:Dynamic array of dynamic (array of struct) 【发布时间】:2011-12-13 07:22:13 【问题描述】:

我有一个名为person 的结构,如下所示:

struct person 
    int height, weight;
;

我还创建了一个person 数组,如下所示:

struct Arrayofperson 
    int len;   //indicates the length of this array(its supposed to be dynamic)
    person *p; //this is supposed to be the dynamic array of person.
;       

我对@9​​87654325@ 的数组执行此操作,如下所示:

struct Array_2d_ofperson
    int len;   //indicates the length of this array(its supposed to be dynamic)
    Arrayofperson *subarray; //this is supposed to be the dynamic 2d array of person.
;   

这是我的代码:

#include <iostream>
#include "test.h"
using namespace std;

#define DLLEXPORT extern "C" __declspec(dllexport)

DLLEXPORT Arrayofperson create_arr_person(int len) 
    Arrayofperson arr_p;
    arr_p.len = len;
    arr_p.p = new person[len];
    //populate the array here:
    for (int a = 0; a < len; a++) 
        arr_p.p[a].height = a; //yes they're the same, but it doesn't matter for now.
        arr_p.p[a].weight = a; 
    ;
    return arr_p;


DLLEXPORT void print_arr_person(Arrayofperson pp) 
    printf("length: %d\n", pp.len);
    for (int b = 0; b < pp.len; b++) 
        printf("height, weight %d, %d\n", pp.p[b].height, pp.p[b].weight);
    ; 


DLLEXPORT Array_2d_ofperson create_2darr_person(int len, int sublen) 
    Array_2d_ofperson arr_2d_person;
    arr_2d_person.len = len;
    arr_2d_person.subarray = new Arrayofperson[len];

    for (int a = 0; a < len; a++) 
        arr_2d_person.subarray[a].len = sublen;
        arr_2d_person.subarray[a].p = new person[sublen];
        for (int b = 0; b < sublen; b++)           
            arr_2d_person.subarray[a].p[b].height = b;
            arr_2d_person.subarray[a].p[b].weight = b;
        
    ;

    for (int a = 0; a < len; a++) 
        for (int b = 0; b < sublen; b++)   
            printf("(a, b): %d, %d", arr_2d_person.subarray[a].p[b].height, arr_2d_person.subarray[a].p[b].weight);
            printf("\n");
        
    ;
    return arr_2d_person;
    cin.get();


DLLEXPORT void print_2darr_person(Array_2d_ofperson pp) 
    int len = pp.len;
    int sublen = pp.subarray[0].len; //yes I haven't forgotten that it can change between different subarrays.

    for (int a = 0; a < len; a++) 
        for (int b = 0; b < sublen; b++)   
            printf("(a, b): %d, %d", pp.subarray[a].p[b].height, pp.subarray[a].p[b].weight);
            printf("\n");
        
    ; 

我打算从上面的代码中制作一个dll(这里为什么不重要)(稍后会有更多代码)并在python中使用它。所以这是我的问题:

1) 似乎当我在 python 端这样做时:

from ctypes import *

test = CDLL('test.dll') //the dll from the code above, yes it works.

arr = test.create_arr_person(6)

test.print_arr_person(arr)

arr2 = test.create_2darr_person(2, 3)

#test.print_2darr_person(arr2)

raw_input('h')

当我尝试打印 2d 数组时,打印人员数组时收到垃圾,并从 Windows 收到访问冲突错误。

所以这是我的问题,按重要性排序(我不想在 dll 中使用 python api,因为 dll 也可以被其他语言使用)

1) 如何使专用于数组/ 2darray 的内存保留在内存中,以免出现访问冲突错误。我试过做静态Arrayofperson,但没用。

2) 如何在二维数组的子数组中轻松访问person 而不是这样做。 pp.subarray[a].p[b]。 (我想这样做:pp[a][b],其中 pp 是人的 2darray)。我相信这与重载[ ] 运算符有关,但我不熟悉制作类(这就是我现在制作结构的原因)。

3) 如何使用相同的方式在 python 中访问数组/2darray(我想在 python 中执行此操作:

test = CDLL('test.dll')
array_of_person = test.create_arr_person(5)
print (array_of_person[0]) #something like this

【问题讨论】:

你想创建人的二维数组......对吗? 我已经知道如何创建数组,但是我不知道如何在函数返回后将其中的信息保持“活跃”。 【参考方案1】:

这里的问题是 python 不知道如何处理你的结构。检查 ctypes 的文档,它有一个可以传递给 C 函数的受支持 python 类型的列表,以及有关如何使其处理更多类型的文档。

按照你写的方式,python 认为你所有的函数都返回一个 int。

你需要阅读http://docs.python.org/library/ctypes.html

编辑: 如果你做对了,你可能最终会从你的 C 函数返回一个指向你的结构的不透明指针到 python。在你的结构中,你可以使用所有 C++ 特性,包括好的东西,比如 std::vector。

【讨论】:

【参考方案2】:

我尝试在 Linux 机器 (gcc 4.4.3) 上编译您的代码,它可以工作。

您是否考虑过使用 STL 容器(向量)?您可以使用向量的向量来生成多维数组,而不必担心内存泄漏。

【讨论】:

向量是 c++,因此我不能使用 extern 'c' 导出它们。我确实尝试过使用向量,但我传递给函数的参数总是错误的。例如:我的 create_array_person 函数采用 'int' 参数,但是当我将 5 传递给它时,我在 dll 端得到类似 2227068 的东西。【参考方案3】:

你可以利用向量被保证是一块连续的内存并返回一个指向第一个元素的指针。

T * p = &v[0]

这个指针可以作为一个普通数组被访问,并且跨模块边界是安全的。 同样的技术也适用于可以通过指向存储的原始指针访问的 std::strings。

const char * p = s.c_str();

您只需要在完成之前确保保存存储的对象不会意外超出范围即可。

多维数组总是可以投影到一维上。

1 1 1

2 2 2

3 3 3

可以存储为:

1 1 1 2 2 2 3 3 3

【讨论】:

以上是关于动态的动态数组(struct数组)的主要内容,如果未能解决你的问题,请参考以下文章

使用 MPI_Type_create_struct() 在 C 中传输包含动态数组的结构

MATLAB中的struct操作

怎么动态分配指针数组

如何定义一个动态的数组?

java的静态数组和动态数组有啥区别?

基于struct内部的元素对指向struct的数组进行排序