声明的数组数据成员没有大小
Array data members declared with no size
我正在努力了解数组在C++中是如何工作的。SO上有一些不错的线索,但有一个问题我找不到答案:
为什么可以声明没有大小的数组数据成员?我认为在C++中,数组大小必须是编译时常数?
示例:
#include<iostream>
class Object{
public:
Object(std::size_t n){
for(std::size_t i = 0; i<n; ++i) { array[i] ='X'; }
//prints 0 because 'sizeof' is compile-time operator
std::cout << "compile-time size: " << sizeof(array) << std::endl;
std::cout << "run-time size " << n << std::endl;
}
private:
char array[];
};
int main( int argc, char** argv )
{
Object obj(10); //10 chars
std::size_t n;
std::cin >> n;
Object obj2(n); //n chars in automatic storage i.e. on the stack??
}
Input:
n = 1000
Output:
compile-time size: 0
run-time size 10
compile-time size: 0
run-time size 1000
这是否意味着obj2的数组数据成员存储在自动存储中,但大小是在运行时动态确定的?
感谢
为什么可以声明没有大小的数组数据成员?
在标准C++中,它不是。在C中,你可以在结构的末尾放一个,以允许一个可变大小的数组,但你必须确保为你想要使用的任何大小分配足够的存储空间。某些C++编译器可能允许将其作为非标准扩展。
这是否意味着obj2的数组数据成员存储在自动存储中,但大小是在运行时动态确定的?
不,这意味着阵列没有任何存储空间,而您正在重写堆栈的其他部分。这不是个好主意。
如果需要动态数组,请使用std::vector
。
根据C++标准(9.2类成员)
9非静态(9.4)数据成员不应具有不完整的类型。在里面特别是,C类不应包含类的非静态成员C、 但是它可以包含指向C类对象的指针或引用。
所以它要么是编译器的特性,要么就是它的bug。
作为类的非静态数据成员的数组存储在分配该类的相应对象的位置。
对于C,则C允许定义结构的柔性阵列成员。
来自C标准(6.7.2.1结构和并集规范)
18作为一种特殊情况,结构的最后一个元素一个命名成员可能具有不完整的数组类型;这被称为柔性阵列成员
但在这种情况下,结构应具有多个命名成员。
C99允许一个名为灵活数组成员的功能。这在C11标准的§6.7.2.11/18中有描述:
作为一种特殊情况,具有多个的结构的最后一个元素命名成员可能具有不完整的数组类型;这被称为柔性阵列构件。在大多数情况下,柔性阵列成员被忽略。
它们不是C++的一部分,但一些编译器允许将它们用作扩展。例如,GCC在其C扩展页面上明确指出了这一点:
ISO C99中的一些特性,但不是C90或C++中的特性,如GCC在C90模式和C++中接受的扩展。
为了兼容性,Clang通常实现GNU扩展。请注意,在所述成员上使用sizeof
似乎是GCC错误或扩展:
灵活数组成员的类型不完整,因此运算符可能不适用。作为原始实现的一个怪癖对于长度为零的数组,sizeof的计算结果为零。
此外,作为类中唯一数据成员的灵活数组成员是GNU扩展。
不可能char数组[]和指向char的指针相同。这意味着你可以做到这一点。
char* pointer;
char array[];
array=pointer;
指针具有值,该值在创建指针时在内存中。简单地指向记忆中的某个地方
数组的工作方式与指针相同。如果int有4个字节,则array[5]指向指针字节后的int 5*4=20。
int array[];
array[5];
*(array+5);
C++在遍历数组后不会抛出异常。通常程序会崩溃,因为默认情况下指针指向程序内存之外的某个位置。
将测试移到从main()调用的新函数中,然后应该会看到堆栈粉碎。
- 是否可以将结构数组别名为结构成员数组?
- C++:初始化 constexpr 构造函数中的成员数组
- 使用带有参数包的数组的成员数组初始化类
- C++ 在析构函数调用之前删除的动态成员数组
- 错误的值是使用c++从CSV文件数据写入数组
- c++用输入数据创建数组
- 初始化在类类型 #define 中定义的非静态成员数组,不带默认 ctor
- 指向具有不同大小的成员数组的指针
- 用另一个 constexpr 数组对成员数组进行大括号初始化
- 对象成员数组C++默认初始化
- 如何将数据从数组复制到C++特征矩阵或向量
- 如何在构造函数中的类成员数组中分配数组值,而无需使用STD库
- 将类成员数组组合到单个数组时性能下降
- 如何将数据从公共方法添加到同一类中的私有成员数组中?
- 如何在C 中的派生类中分配数据成员数组
- C 集合构建器中类成员数组的2D数组大小
- 如何在 c++ 中从对象数组中获取数据成员数组
- 在VS2012上将数据成员数组元素初始化为零
- 如何在所示代码中对类的两个数据成员数组进行排序
- 非静态数据成员(数组)的使用无效