【问题标题】:Why I get access writing violation when using memset with a big _Size?为什么在使用带有大 _Size 的 memset 时出现访问写入冲突?
【发布时间】:2020-01-18 19:29:34
【问题描述】:

所以我的 C++ 代码中有一个 _Scalar 类型的变量,它可以采用很多不同的类型(int、double ...)。

所以我在我的模板类中使用 new 操作符来初始化我的指针。当我想分配内存时,我在我的模板类的构造函数中使用了 memset 函数。

//At the beginning of the class
_Scalar* m_data;

//In the constructor
m_data = new _Scalar;
memset(m_data, 0, sizeof(_Scalar) * m_size)

例如,对于 15 的 m_size,一切正常。但是当m_size 是10000 时,我得到一个访问写入冲突错误。我在 Visual Studio 中观看了 m_data 变量,这就是我得到的:

那么问题是什么以及如何解决呢?我对 C++ 很陌生。

【问题讨论】:

  • 当你只分配一个却尝试初始化10000,当然不行。
  • new _Scalar 只分配一个 _Scalar 实例,你想要new _Scalar[m_size],你正在耗尽内存并且幸运的是 m_size = 15。
  • std::vector<_Scalar> m_data 可能是更好的选择。
  • P.S.不要在 C++ 中使用 memset,除非您知道该变量是 POD 类型。
  • 什么是_Scalar?如果它是由用户代码声明的,那么您应该知道禁止声明以下划线开头后跟大写字母的标识符。这些标识符保留给编译器/标准库实现。违反此规则会导致程序具有未定义的行为。

标签: c++ memory memset


【解决方案1】:

我怀疑你真的想要这个:

m_data = new _Scalar[m_size];
for (int i = 0; i < m_size; i++) {
   m_data[i] = {};
}

或者正如其他人指出的那样,这就足够了:

m_data = new _Scalar[m_size]();

根据 Scalar 对象内部的内容,memset 可能安全也可能不安全。我已经看到一些糟糕的失败,因为 memset 被用来“清零”一个包含分配内存的成员的对象。

更好的方法可能是让 Scalar 的构造函数确保所有成员都归零。取决于您是否可以控制该类的代码。

【讨论】:

  • 为什么不直接初始化它:m_data = new _Scalar[m_size]();
  • 哦,是的,它也很有效,哈哈。我不知道我的老师想要什么
  • memset 完全按照它所说的去做,并将一个精确的位模式写入一个内存范围。当您的对象不符合您对它们的位模式应该是什么的期望时,问题就出现了。
  • @ÉmilePettersen-Coulombe 在 C++ 中使用 memset 几乎没有任何意义(但在 C 中有)。在 C++ 中,您可以如上所示直接正确初始化内存,或者使用std::fill,它与memset 相同,但对于普通类型是类型安全的,并且对于非普通类型也能正确运行。
猜你喜欢
  • 2018-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 2011-12-04
  • 1970-01-01
相关资源
最近更新 更多