Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
这是C++;结构黑客的替代方案? 是下面的C++吗?这是将可变长度尾部实现为扁平结构的另一种方法。在C中,这通常是通过 结构Str { Str(int c):计数(c){} 大小/数量; Elem*data(){return(Elem*)(this+1);} }; Str*Str=(Str*)新字符[sizeof(Str)+sizeof(Elem)*计数]; 新(str)str(计数); 对于(int i=0;idata()+i)元素(); str->data()[0]=elem0; str->data()[1]=elem1; //等等。。。_C++ - Fatal编程技术网

这是C++;结构黑客的替代方案? 是下面的C++吗?这是将可变长度尾部实现为扁平结构的另一种方法。在C中,这通常是通过 结构Str { Str(int c):计数(c){} 大小/数量; Elem*data(){return(Elem*)(this+1);} }; Str*Str=(Str*)新字符[sizeof(Str)+sizeof(Elem)*计数]; 新(str)str(计数); 对于(int i=0;idata()+i)元素(); str->data()[0]=elem0; str->data()[1]=elem1; //等等。。。

这是C++;结构黑客的替代方案? 是下面的C++吗?这是将可变长度尾部实现为扁平结构的另一种方法。在C中,这通常是通过 结构Str { Str(int c):计数(c){} 大小/数量; Elem*data(){return(Elem*)(this+1);} }; Str*Str=(Str*)新字符[sizeof(Str)+sizeof(Elem)*计数]; 新(str)str(计数); 对于(int i=0;idata()+i)元素(); str->data()[0]=elem0; str->data()[1]=elem1; //等等。。。,c++,C++,我这样问是为了回应以下问题:不,这是无效的: 元素可能与Str具有不同的对齐方式,因此(重新解释)将Str+1强制转换到Elem*可能会给您一个有效的指针,也可能不会给您一个有效的指针,而访问可能会给出未定义的行为 但毕竟,你为什么要这样做呢?在什么意义上有效?它是C++的,使用C类技术,只要项目要求没有其他选择,IMHO就很好。 如果您询问它是否会工作,只要数据对齐问题不会使代码崩溃(即非x86,如SPARC等),它就会工作。C++在处理内存时的行为类似于C。 我在gcc和VS下使用以下修改对

我这样问是为了回应以下问题:不,这是无效的:

元素可能与
Str
具有不同的对齐方式,因此(重新解释)将
Str+1
强制转换到
Elem*
可能会给您一个有效的指针,也可能不会给您一个有效的指针,而访问可能会给出未定义的行为


但毕竟,你为什么要这样做呢?

在什么意义上有效?它是C++的,使用C类技术,只要项目要求没有其他选择,IMHO就很好。 如果您询问它是否会工作,只要数据对齐问题不会使代码崩溃(即非x86,如SPARC等),它就会工作。C++在处理内存时的行为类似于C。 我在gcc和VS下使用以下修改对其进行了测试,结果表明它可以正常工作:

struct Elem
{
Elem() : x(0), t(0) { memset(c, 0, sizeof(c));} 
Elem(int v) : x(v), t(0) { memset(c, 0, sizeof(c));} 
Elem(const Elem &e) { *this = e; }

Elem &operator=(const Elem &e)
{
    if (this != &e)
    {
         memcpy(c, e.c, sizeof(c));
         x = e.x;
         t = e.t;
    }
    return *this;
}

char c[21];
int x;
char t;
};

struct Str
{
    Str(int c) : count(c) {}
    size_t count;
    Elem* data() { return (Elem*)(this + 1); }
};

int count = 11;

Str *str = (Str*)new char[sizeof(Str) + sizeof(Elem) * count];
new (str) Str(count);
for (int i = 0; i < count; ++i)
{
    new (str->data() + i) Elem();
    str->data()[i] = Elem(i+1);
}

for (int i=0; i<str->count; i++)
    cout << "[" << i << "]: " << str->data()[i].x << endl;
结构元素 { Elem():x(0),t(0){memset(c,0,sizeof(c));} 元素(intv):x(v),t(0){memset(c,0,sizeof(c));} Elem(const Elem&e){*this=e;} 电气和操作员=(常量电气和电气) { 如果(此!=&e) { memcpy(c、e.c、sizeof(c)); x=e.x; t=e.t; } 归还*这个; } charc[21]; int x; 查尔特; }; 结构Str { Str(int c):计数(c){} 大小/数量; Elem*data(){return(Elem*)(this+1);} }; 整数计数=11; Str*Str=(Str*)新字符[sizeof(Str)+sizeof(Elem)*计数]; 新(str)str(计数); 对于(int i=0;idata()+i)元素(); str->data()[i]=Elem(i+1); } for(int i=0;i计数;i++)
如果
Elem
Str
具有不同的对齐方式,我想这是行不通的。这很容易解决:
union{size\u t count,Elem dummy;}
如果你真的想做得漂亮,可以使用模板元编程来使
dummy
成为
Elem
std::max\u align\t
中较小的一个。这可能行得通。问题是为什么你会在C++中做这种事情。有更好的方法来编写动态同构指针容器。为什么?低级黑客。但这似乎是一个问题,谢谢。通常的原因是引用的位置。另请参见
std::make_shared
。此外,IIRC
new char[]
适合所有类型(能够作为
malloc
的替代品)@MSalters:
new char[]
适合对齐,但在偏移
Str
后,所有下注都被取消。@MatthieuM。的确,但我的话是关于第一颗子弹的。这就是声称
new[]
没有返回合适的对齐内存的方法。问题在于尾随数组。(正如我所评论的,这种对齐方式是固定的)@MSalters:实际上,
newchar[]
可能并没有针对所有类型正确对齐
newchar[]
仅保证对所有标准类型进行正确对齐,即达到
alignof(std::max_align_t)
。虽然这取代了所有可能作为这些类型组合创建的类型,但有一些特定的向量类型用于SSE/AVX指令,例如可能有更严格的对齐要求(通过编译器内部函数指定),这些不在本保证范围内。当然,在这种情况下,它应该适用于
Str
struct Elem
{
Elem() : x(0), t(0) { memset(c, 0, sizeof(c));} 
Elem(int v) : x(v), t(0) { memset(c, 0, sizeof(c));} 
Elem(const Elem &e) { *this = e; }

Elem &operator=(const Elem &e)
{
    if (this != &e)
    {
         memcpy(c, e.c, sizeof(c));
         x = e.x;
         t = e.t;
    }
    return *this;
}

char c[21];
int x;
char t;
};

struct Str
{
    Str(int c) : count(c) {}
    size_t count;
    Elem* data() { return (Elem*)(this + 1); }
};

int count = 11;

Str *str = (Str*)new char[sizeof(Str) + sizeof(Elem) * count];
new (str) Str(count);
for (int i = 0; i < count; ++i)
{
    new (str->data() + i) Elem();
    str->data()[i] = Elem(i+1);
}

for (int i=0; i<str->count; i++)
    cout << "[" << i << "]: " << str->data()[i].x << endl;