我对刚遇到的错误感到有些困惑。我正在使用Visual Studio 2015,我遇到了不一致的行为。我已经从它所在的项目中删除了代码并重新创建了行为,请允许我引导您完成代码:
template <typename Ty>
struct Simple_Array
{
Ty* data;
const size_t size;
Simple_Array(size_t size) :
size(size),
data(new Ty[size])
{
}
virtual ~Simple_Array() {
delete[] data;
}
};
正如你所看到我在我的代码中使用一个简单的c数组包装器,我想使用一个c数组来进行自学,因此不使用像std :: vector或std :: array这样的东西。使用这个时,我发现需要一个构造函数,它将第一个和最后一个迭代器放在任何其他容器上,所以我决定使用std :: distance(first,last)来计算大小。
template <class It>
Simple_Array(It first, It last) :
size(std::distance(first, last)),
data(new Ty[size])
{
for (int i = 0; first != last; ++first, ++i)
data[i] = *first;
}
现在,当我使用这个构造函数时,大小被初始化为疯狂的大值,例如3435973836.为什么?这特别令人困惑,因为以下代码可以正常工作:
template <class It>
Simple_Array(It first, It last) :
Simple_Array(std::distance(first, last))
{
for (int i = 0; first != last; ++first, ++i)
data[i] = *first;
}
为了测试这个,我编写了以下主要功能:
int main() {
auto list = { 1, 2, 3, 4 };
try {
Simple_Array<int>(list.begin(), list.end());
}
catch (...) {
std::cout << "Failed." << std::endl;
}
std::cin.get();
return 0;
}
我看了一下反汇编,但我还没弄清楚问题是什么。好消息是因为我有一个解决方法,我不需要回答这个问题来继续我的项目,但我仍然非常想知道这里出了什么问题。
我在这里粘贴了整个文件:pastebin.com/ebNrsLaB
答案 0 :(得分:3)
哇!这是我生命中第一次看到臭名昭着的关于初始化顺序的gcc警告。
特别是,类成员按照它们在类中定义的顺序进行初始化,而不是按照它们在构造函数初始化列表中列出的顺序进行初始化。由于您的Ty* data;
是在size
之前定义的,因此在将大小设置为实际值之前对其进行初始化(已分配) - 使用未初始化大小的随机值。
要解决此问题,请确保在类中的数据之前定义大小。
答案 1 :(得分:1)
struct Simple_Array
{
Ty* data; // (1)
const size_t size; // (2)
Simple_Array(size_t size) :
size(size), // (2)
data(new Ty[size]) // (1)
{
}
成员变量按照它们在结构中声明的顺序进行初始化,不按照在构造函数初始化列表中编写它们的顺序进行初始化。
编译器应该警告你。