非同构数组的内存分配如何工作?

时间:2016-10-02 07:35:39

标签: c

使用struct elements { int s; union { int ival; float fval; char *pval; } element; }; struct darray { struct elements items[100]; }; ,我们当然可以拥有一个包含不同数据类型元素的数组。

e.g。

struct darray a;

现在,我们可以声明一个可以包含不同数据类型元素的数组:

$response = [];
while ($row = oci_fetch_array($array)) {
  $response[] = $row['0']->load();
}

var_dump($response);

令我不安的是:联盟中只有一个联盟成员可以同时存在,但我们已经有一个包含100个元素的数组。这些元素没有初始化,但是不应该在这里分配内存吗?

内存分配如何在这样的数组中工作?

2 个答案:

答案 0 :(得分:1)

数组是同构的,但它的内容包括一个联合,它可以代表使用相同底层内存的不同类型。

每个元素都是自己的对象,具有自己的成员s和元素。

您可以自由地为不同的元素分配不同的类型:

enum
{
    INT , 
    FLOAT , 
    STRING ,
} ;

struct darray a;
a.items[0].s = INT;
a.items[0].element.ival = 12345;
a.items[1].s = FLOAT;
a.items[1].element.fval = 4.56F;
a.items[2].s = STRING;
a.items[2].element.pval = "string literal";

printf( "%d %f %s\n" , a.items[0].element.ival , 
                       a.items[1].element.fval , 
                       a.items[2].element.pval );

您可以简单地定义类型为struct element的数组,而不是将类型struct元素包装到struct darray类型中:

struct elements a[100];

答案 1 :(得分:0)

让我们看看以下代码:

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

typedef union __attribute__((__packed__)) {
    int   ival;
    int   fval;
    char* pval;
} element;

typedef struct __attribute__((__packed__)) { 
    int     s;
    element e;
} elements;

typedef struct __attribute__((__packed__)) {
    elements items[100];
} darray;

int main()
{
    darray d = {0};
    printf("size of element: %lu.\n", sizeof(element));
    printf("size of elements: %lu.\n", sizeof(elements));
    printf("size of darray: %lu.\n", sizeof(darray));
    return 0;
}
// The output is:
//  size of element: 8
//  size of elements: 12
//  size of elements: 1200

现在让我们来解释刚刚发生的事情:

  1. 我正在使用64位计算机,因此指针的大小为8。
  2. 我们使用__attribute__((__packed__))来强制编译器不用额外的内存字节填充我们的结构。这就像告诉他一样,使用构建包含以下成员的结构所需的最少内存量。
  3. 请注意,虽然现在element正在携带的是什么,但它已经具有编译时的大小。元素的大小是8,为什么?联合大小由其较大的成员修复(这里我们有int,它是4,float是4,而char*是8 [64位机器再次...] )。
  4. 现在我们知道union有一个固定的大小,创建100个成员的数组,需要100 * sizeof(elements) = 100 * (sizeof(int) + sizeof(element)) = 100 * (4 + 8) = 1200字节的内存。