类成员是否在内存中是连续的? [英] Are class members garaunteed to be contiguous in memory?

查看:152
本文介绍了类成员是否在内存中是连续的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类,它包含一些函数指针,我想他们所有的对象被构​​造时被初始化为NULL。为了做到这一点,我计划在内存位置使用memset从第一个指针到最后一个指针,但我不确定这是否将100%的时间工作。

I have a class which holds a number of function pointers and I would like for them all to be initialised to NULL when objects are constructed. To do this I was planning on using memset on the memory locations from the first pointer to that of the last pointer however, I am unsure if this would work 100% of the time.

它保证,如果这些函数指针在类中被连续地声明,它们的内存位置也将是连续的。我假设padding不会影响我想做的任何填充字节也将被设置为NULL。

Is it guaranteed that if these function pointers are declared contiguously within the class that their memory locations would also be contiguous. I assume that padding won't affect what I'm trying to do as any padding bytes would just be set to NULL also.

示例类实现

class C
{
private:
    void (*func1)();
    void (*func2)();
    void (*func3)();
    void (*func4)();
};


推荐答案

订单声明。这通常是没有中间访问说明符的数据成员,所以如果在类中有其他数据成员,那么他们可以干预的唯一方法是如果有访问说明符。

It is guaranteed that they appear with increasing addresses in the order declared. This is true in general of data members without intervening access specifiers, so if there are other data members in the class then the only way they could intervene is if there are access specifiers in there.

我不认为它可以安全地修改填充字节。我不认为它保证实现不会在数据成员之间重要的一些东西,虽然我不能立即想到任何实现将要想要放在那里。类型信息为一个奇怪设计的精确标记GC?可识别的值来测试缓冲区溢出?

I don't think it's guaranteed to be safe to modify padding bytes. I don't think it's guaranteed that the implementation won't put "something important" in between data members, although I can't immediately think of anything an implementation would want to put in there. Type information for a strangely-designed accurate-marking GC? Recognizable values to test for buffer overruns?

不能保证所有位零表示一个空函数指针。

It's not guaranteed that all-bits-zero represents a null function pointer.

您可以使用以下类型来处理所有位零表示的问题:

You could deal with the issue of the all-bits-zero representation using something like:

std::fill(&func1, &func4 + 1, (void(*)(void))0);

但这仍然会留下填充的问题。你可以保证在数组中没有填充,但不能在类中使用。您的实现使用的ABI可能会指定结构布局以确保您的类上面的布局与4个函数指针的数组相同。

but that would still leave the issue of padding. You're guaranteed no padding in an array, but not (by the standard) in a class. The ABI used by your implementation might specify struct layout to the degree necessary to ensure that your class above is laid out the same as an array of 4 function pointers.

是执行以下操作:

struct function_pointers {
    void (*func1)();
    void (*func2)();
    void (*func3)();
    void (*func4)();
};

class C : private function_pointers
{
public:
    C() : function_pointers() {}
};

初始化程序 function_pointers()因为它没有用户声明的构造函数) function_pointers 的成员是零初始化的,即使 C 本身只是默认初始化。 function_pointers 可以是一个数据成员而不是一个基类,如果你更喜欢键入一些来访问 func1 等。

The initializer function_pointers() dictates that (since it doesn't have a user-declared constructor) the members of function_pointers are zero-initialized even if the instance of C itself is only default-initialized. function_pointers could be a data member rather than a base class, if you prefer to type a bit more to access func1 etc.

请注意,在C ++ 03中 C 现在是非POD。在C ++ 11 C 在此更改后仍然是标准布局,但是如果在 C ,它不是一个简单的类。所以如果你依靠POD / standard / trivial-ness,那么不要这样做。而是保留 C 的定义,并使用聚合初始化( C c = {0}; )为零 - 初始化C的实例。

Note that C is now non-POD in C++03. In C++11 C remains standard-layout after this change, but would not be standard-layout if there were any data members defined in C, and it is not a trivial class. So if you were relying on POD/standard/trivial-ness then don't do this. Instead leave the definition of C as it is and use aggregate initialization (C c = {0};) to zero-initialize instances of C.

这篇关于类成员是否在内存中是连续的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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