结构中的零大小数组 [英] zero size array in structure

查看:102
本文介绍了结构中的零大小数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

直接在函数中声明零大小的数组(例如

Declaring zero sized array say

int x[0];

)会导致编译器错误.
我们不允许创建大小为零的数组.

但是,当我们创建一个具有零大小数组的结构时,为什么要允许它呢?

directly in function gives compiler error.
We are not allowed to create an array of zero size.

But when we create a structure have this zero size array then why it is allowed?

struct xyz
{
    int x;
    char y;
    int z[0];
};
struct xyz C;


为什么sizeof(C)返回8个字节?


Why does sizeof(C) returns 8 bytes?
What might be the purpose of inserting such zero sized array in structure?

推荐答案

这是一个占位符-这意味着该结构每次都不会具有相同的大小,这可能是什么目的?返回.
基本上,考虑一个根据您的值返回信息的结构:如果您请求网络上所有计算机的Ids,它都会返回一个Ids数组.如果您要求特定的机器ID,则该阵列未使用.
这是C的宿醉,坦率地说,有更好的方法可以在C ++中做到这一点.
It is a placeholder - it means that the struct will not have the same size every time it is returned.
Basically, think about a structure that returns information, based on the value you as for: if you ask for Ids for all machines on the network, it returns an array of Ids. If you ask for a specific machine id, the array is unused.
It''s a hangover from C, and frankly there are better ways to do this in C++


这是从C继承的一种做法.但是您的第一个问题是无关紧要的.

为什么要8个字节


8位微处理器已经不再需要以字节为单位物理地组织内存了.具有较大字"的处理器不会将字节作为其本机单元移动.实际上,访问各个字节需要处理器进行屏蔽和移位.为了证明这种惩罚性",将各个结构字段对齐"在处理器字边界"上.对于32位处理器,这是4个字节.
您的结构长度为8个字节,因为4个用于int x,其他4个用于char y(1是char,其他3是padding).

什么是零尺寸


C没有像C ++那样强类型化",并且不具有对动态结构的支持".
大小为零的数组本质上是一种允许像
这样的表达式的方式
That''s a practice inherited from C. But your first question is unrelated.

Why 8 bytes


The day where memory was physically organized in bytes has gone with the 8bit microprocessors. Processor with larger "words" don''t move bytes as their native unit. Accessing individual bytes, in fact, requires to the processor a masking and a shift. To avid this "penality" individual struct fields are "aligned" on a "processor word boundary". For 32 bit processor this is 4 bytes.
Your struct is 8 bytes long because 4 serves the int x, and other 4 serves char y (1 is the char, the other 3 are padding).

What''s the zero size


C is not "strongly typed" as C++ is, and has no "support for dynamic structures".
The zero sized array is essentially a way to allow expression like
C.z[3]


允许您访问结构起始地址之后的4 rd (3 + 1)int.
在您的情况下(C在堆栈中),这将编写其他内容(导致未定义的行为)

但是有了动态内存,这个主意就像是


allowing you to access the 4rd (3+1) int after the struct beginning address.
In your case (where C is on-stack) this will write something else (causing undefined behavior)

But with dynamic memory, the idea is something like

// get enough raw memory
xyz* ptr = (xyx*)malloc(sizeof(xyz)+4*sieof(int));
// in-pace construct the C++ variables (not really needed here, being xyz a POD
new(ptr) xyz;
new(&ptr->z)int[4];
// do something with the variables
ptr->x = 1;
ptr->y = ''a'';
ptr->z[0] = 10;
ptr->z[1] = 11;
ptr->z[2] = 12;
ptr->z[3] = 13; //< no more than this, otherwise will go out of memory
/*
 * your useful stuff goes here
 */
// explicitly destroy C++ objects (not really needed being xyz a POD)
for(i=0;i<4;++i) p->z[i].~int();
ptr->~xyx();
// return the raw memory to the system
free(ptr);



如今,由于多种原因,这已经是有效的C ++代码(malloc 无需构造即可分配内存,因此,如果xyz包含除普通存储之外的其他代码,则需要就地构建和显式就地破坏数据,例如需要构造的对象),但仍必须使用低级的东西(必须以给定的方式对内存进行布局).

更现代的C ++代码可能会像
那样定义您的结构



Today this is anymore valid C++ code for a variety of reasons (malloc allocates memory without contruction, so in-place construction and explicit in-place destruction are required, in case xyz contains somting other than plain data, like object requiring construction), but to access low level stuff where the memory has to be layed-out in a given way, can still be in use.

More modern C++ code will probably define your struct like

#include <vector>
struct xyz
{
    int x;
    char y;
    std::vector<int> z; //now z is anymore an "array" but a dynamic structure
    // construct by specfying the initial z size
    explicit xyz(size_t vectsize)
        :x(), y(), z(vectsize)
    {}
};


int main()
{
    xyz C(4);
    C.x = 1;
    C.y = ''a'';
    c.z[0] = 10;
    c.z[1] = 20;
    c.z[2] = 30;
    c.z[3] = 40;
    /*
     * all other stuffs
     */
    return 0; //destruction is automatic from here
}



但是生成的内存布局将完全不同(std :: vector仅包含指向动态分配内存的指针")



But the resultingmemory layout will be completely different (std::vector contains just "pointers" to a dynamically allocated memory)


这篇关于结构中的零大小数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆