C++ C+中的变长结构非标准+;11?

C++ C+中的变长结构非标准+;11?,c++,c++11,C++,C++11,可能重复: 我检查了C++11中是否允许使用零长度数组。看来他们不是。从8.3.4阵列[dcl.array] 如果存在常数表达式(5.19),则其应为积分常数表达式,且其值应大于零 既然我不能使用零长度数组,那么在标准/良好定义的情况下是否可以使用可变长度结构?例如,我想做如下的事情。当缓冲区可能为空时,如何使其定义良好并成为标准 -编辑相关: struct MyStruct{ 单位尺寸; int32 buf[0];//大小=len memcpy(p->buf,ptr,bytelen) 返回p

可能重复:

我检查了C++11中是否允许使用零长度数组。看来他们不是。从
8.3.4阵列[dcl.array]

如果存在常数表达式(5.19),则其应为积分常数表达式,且其值应大于零

既然我不能使用零长度数组,那么在标准/良好定义的情况下是否可以使用可变长度结构?例如,我想做如下的事情。当缓冲区可能为空时,如何使其定义良好并成为标准

-编辑相关:

struct MyStruct{
单位尺寸;
int32 buf[0];//大小=len
memcpy(p->buf,ptr,bytelen)
返回p;

结构黑客从来都不是标准的。这应该是一个标准的可行替代品:

struct MyStruct {
    uint size;
    int32 buf[1];
};
否*

使用
std::vector


<> p> *我假设C++没有添加任何与C在这个区域中的规则相矛盾的规则。IMO是不太可能的,虽然我没有时间来验证。

这是C++,不是c。你不需要这个C++中的灵活数组成员破解,因为你可以很容易地制作一个模板类,它可以赋予任何一个结构灵活的数组。并封装指针算术计算和内存分配以使其正常工作。注意:

#include <cstring>

template <typename STRUCT, typename TYPE> class flex_struct {
public:
  TYPE *tail()
  {
    return (TYPE *) ((char *) this + padded_size());
  }

  // substitute malloc/free here for new[]/delete[] if you want
  void *operator new(size_t size, size_t tail)
  {
    size_t total = padded_size() + sizeof (TYPE) * tail;
    return new char[total];
  }

  void operator delete(void *mem)
  {
    delete [] (char *) mem;
  }
private:
  static size_t padded_size() {
    size_t padded = sizeof (flex_struct<STRUCT, TYPE>);
    if(padded % alignof(TYPE) != 0) {
         padded = padded & ~(alignof(TYPE)-1) + alignof(TYPE);
    }
    return padded;
  }
};

struct mystruct : public flex_struct<mystruct, char> {
  int regular_member;
};

int main()
{
  mystruct *s = new (100) mystruct; // mystruct with 100 chars extra
  char *ptr = s->tail();            // get pointer to those 100 chars
  memset(ptr, 0, 100);              // fill them
  delete s;                         // blow off struct and 100 chars
}
#包括
模板类flex_结构{
公众:
类型*tail()
{
返回(TYPE*)((char*)this+padded_size());
}
//如果需要,请将malloc/free替换为new[]/delete[]
void*运算符新(大小、大小尾)
{
总尺寸=填充尺寸()+尺寸(类型)*尾部;
返回新字符[总数];
}
void运算符删除(void*mem)
{
删除[](字符*)成员;
}
私人:
静态大小\u t填充大小(){
尺寸加垫=尺寸(柔性结构);
如果(填充的对齐百分比(类型)!=0){
padded=padded&~(alignof(TYPE)-1)+alignof(TYPE);
}
返回填充;
}
};
struct mystruct:public flex_struct{
国际正规大学成员;
};
int main()
{
mystruct*s=new(100)mystruct;//额外添加100个字符的mystruct
char*ptr=s->tail();//获取指向这100个字符的指针
memset(ptr,01100);//填充它们
删除s;//清除结构和100个字符
}

在Ung> Buf,分配的内存,UB仍然是UB,不是吗?@ LeNeNeSraceSeNe轨道不,我想不是UB。我希望我没有错;我只是发现了。很显然,它是C中的UB,因此最有可能是C++中的well@LightnessRacesinOrbit它是一个数组对象。请参见§5.3.4[解释新内容]p5@bames53:啊,太好了!“我想对新[]是有补贴的”似乎应该回答“是的,有。”“那么。好吧,我解开了我的DV,但问题是关于如何定义结构。我对如何分配内存没有问题。例如,指针可能指向fread中使用的buf,如果最后4个字节是
大小
。我认为
buf[1]
是错误的/非法的?而“使用
std::vector
”在一般情况下,变长
struct
hack是最好的建议,当您希望尽可能消除间接性时,因此
vector
可能不是最好的选择。@JonPurdy:它是唯一满足问题所述的标准合规性和定义行为要求的选项,而不是静态的我分配了一个巨大的数组,你只使用了其中的一部分。但答案与我的问题无关。你没有说我是否可以将buf定义为0长度,甚至1长度,也没有提到对齐等等。这就是我最初使用DV的原因it@acidzombie24当前位置这与您的问题有关。您问您是否可以遵从答案是“不”。VJVIC:注意,问题是关于C不是C++ 11,甚至C++,如果我告诉你C++中的C有多少(C++ 11),你不应该感到惊讶。我喜欢这个答案。但出于某种原因,我不相信这会起作用。我将编写代码来解决问题。+1它可能不起作用,因为它不符合某些人的特定要求,但我用g++-Wall-ansi编译了代码,并在valgrind下运行了./a.out:无错误。我无法找到任何其他方法来编写co你写的。最大的问题是对齐。假设你的成员是4或6个字节,数组类型是长的,需要8个字节对齐。这是错误的。另外,新的是不正确的,因为你有100个额外的字节,没有对常规成员进行大小调整,但我知道如何解决这个问题,以及你的实际点。这既不符合标准,也不符合标准可移植性。考虑<代码> StultS:公共FrimeStult{char C;}。
。如果将结构分配到对齐的地址
X
,则
int
数组从未对齐的地址
X+1
开始。未对齐的指针可能会发生不好的情况。我尝试过解决对齐问题。我想也可以在C++03中使用
boost::alignment\u of
#include <cstring>

template <typename STRUCT, typename TYPE> class flex_struct {
public:
  TYPE *tail()
  {
    return (TYPE *) ((char *) this + padded_size());
  }

  // substitute malloc/free here for new[]/delete[] if you want
  void *operator new(size_t size, size_t tail)
  {
    size_t total = padded_size() + sizeof (TYPE) * tail;
    return new char[total];
  }

  void operator delete(void *mem)
  {
    delete [] (char *) mem;
  }
private:
  static size_t padded_size() {
    size_t padded = sizeof (flex_struct<STRUCT, TYPE>);
    if(padded % alignof(TYPE) != 0) {
         padded = padded & ~(alignof(TYPE)-1) + alignof(TYPE);
    }
    return padded;
  }
};

struct mystruct : public flex_struct<mystruct, char> {
  int regular_member;
};

int main()
{
  mystruct *s = new (100) mystruct; // mystruct with 100 chars extra
  char *ptr = s->tail();            // get pointer to those 100 chars
  memset(ptr, 0, 100);              // fill them
  delete s;                         // blow off struct and 100 chars
}