【发布时间】:2020-04-01 11:44:38
【问题描述】:
我正在从事一个 AI 项目,并已开始实现一个 NeuralNetwork 类。我只是想了解一些基本的东西,所以我使用了一些 malloc 语句和一些放置新闻,最后删除 []s。
但是,一旦 NeuralNetwork 对象(在 main 函数中的堆栈上创建)即将被删除(我在析构函数的开头设置了一个断点),我的数组似乎已被提前删除(值 0xcccccccc)并且因此 delete[] 语句会引发访问冲突。
通过进一步调查,我发现这种删除发生在最后一个 Vector 对象被销毁和我的 NeuralNetwork 对象的析构函数开始被调用之间。
我确保同时实现了复制构造函数和赋值运算符,以确保在我注意到的情况下不会发生复制。
我真的对这个问题感到困惑,希望有人能发现我的错误。源代码如下:
NeuralNetwork::NeuralNetwork(const std::initializer_list<size_t>& l):
m_size(l.size() - 1),
m_weights(static_cast<Matrix<double>*>(malloc(sizeof(Matrix<double>) * m_size))),
m_biases(static_cast<Vector<double>*>(malloc(sizeof(Vector<double>) * m_size)))
{
size_t index = 0;
auto itr = l.begin();
for (auto next = itr + 1; next != l.end(); ++next, ++itr, ++index)
{
new (m_weights + index) Matrix<double>(*next, *itr);
new (m_biases + index) Vector<double>(*next);
}
}
NeuralNetwork::NeuralNetwork(const NeuralNetwork& nn) :
m_size(nn.m_size),
m_weights(static_cast<Matrix<double>*>(malloc(sizeof(Matrix<double>)* m_size))),
m_biases(static_cast<Vector<double>*>(malloc(sizeof(Vector<double>)* m_size)))
{
for (size_t index = 0; index < m_size; ++index)
{
new (m_weights + index) Matrix<double>(nn.m_weights[index]);
new (m_biases + index) Vector<double>(nn.m_biases[index]);
}
}
NeuralNetwork::NeuralNetwork(NeuralNetwork&& nn) noexcept :
m_size(nn.m_size),
m_weights(nn.m_weights),
m_biases(nn.m_biases)
{
nn.m_size = 0;
nn.m_weights = nullptr;
nn.m_biases = nullptr;
}
NeuralNetwork::~NeuralNetwork()
{
delete[] m_weights; // exception thrown here, value is 0xcccccccc, nullptr
delete[] m_biases;
}
主要代码:
int main()
{
NeuralNetwork nn{ 2, 1 };
Vector<double> input(2);
input.Get(0) = 0.5;
input.Get(1) = 0.25;
Vector<double> output = nn.Forward(input); // just does the math, nothing special
for (size_t i = 0; i < output.GetSize(); ++i)
std::cout << output.Get(i) << " ";
std::cout << std::endl;
}
如果缺少任何重要的源代码,请告诉我,谢谢!
【问题讨论】:
-
你为什么要这么做
static_cast+malloc魔法?此外,delete[]是一对new[]。顺便提一句。new,人们通常想存储他们的结果,你只需在各种循环中调用它们。 -
我将它们存储在权重和偏差数组中。 m_weights + index 是指向存储它们的地址的指针
-
我使用 malloc + cast 因为我不想默认构造数组
-
在is初始化后在内存上添加数据断点,可以找到修改的地方
标签: c++