【问题标题】:Why memset is not working with array container in c++11?为什么 memset 不能在 c++11 中使用数组容器?
【发布时间】:2015-06-29 11:26:47
【问题描述】:
#include <iostream>
#include <array>
#include <cstring>

using namespace std;

int main ()
{
  array<int,5> A ;
  memset(A,0,sizeof A);
  for(int i=0;i < 5;i++){
        cout<<A[i]<<" ";
}

   return 0;
}

运行程序时出现编译错误。

但是当我使用int A[5] 而不是array&lt;int,5&gt; A 时,memset 效果很好。为什么 memset 不能与容器数组一起使用,因为这两种方法都用于定义固定大小的数组?

【问题讨论】:

  • 为什么不直接使用array&lt;int, 5&gt; A = {};/int A[5] = {};
  • 不要在非 POD 类型上使用 memset
  • 什么是非 POD 类型
  • 非 POD 类型:具有构造函数的类型
  • @CoryKramer:std::array 的大部分意义在于它是一种 POD 类型。不过,同意memset 在这里是不必要的,应该避免。

标签: c++ arrays c++11


【解决方案1】:

密切关注memset的声明:

void * memset ( void * ptr, int value, size_t num );

注意第一个参数必须是指针。

原始数组是 C++ 中的特殊事物。您不能将它们作为参数传递给这样的函数,但如果函数将指针作为参数,则适当类型的数组将 decay 指向第一个元素的指针。这就是为什么您可以将原始数组传递给需要指针的函数。

std::array 不是原始数组,而是常规类。类实例不会衰减为指针。这就是为什么不能将std::array 的实例作为memset 的参数传递的原因。

正如 cmets 中已经解释的那样,无论如何您都不应该使用 memset 来初始化 std::array

【讨论】:

    【解决方案2】:

    std::memset 应该可以与std::array 一起正常工作。如果您查看std::memset 的声明,您会发现它需要一个指向数组的指针,这就是您的代码不起作用的原因。

    void* memset( void* dest, int ch, std::size_t count );
    

    这应该可行:

    memset(A.data(), 0, A.size() * sizeof(A[0]);
    

    就像其他人指出的那样,在你的例子中最好初始化数组

    array<int, 5> A = {};
    

    【讨论】:

    • 你这里对memset的使用有问题。 Aint 的数组,memset 填充 字节 的内存。传递A.size()元素 的数量,您需要按元素的大小 对其进行缩放。更好的是,只需使用std::array::fill 成员函数...
    • @Blastfurnace 谢谢,没注意。将修复代码。我知道 memset() 在这种情况下不好用,但问题不是问它好不好,而是问为什么它不起作用。
    • 您的解决方法不太正确,A.size() 是元素的数量,因此您希望将其乘以元素的大小以获得字节数填充。
    • @Blastfurnace Ups 再次 :) 谢谢!
    【解决方案3】:

    memset(A,0,sizeof A); 不正确。这是一种反模式。将对象设置为全位为零(对于允许此操作的对象)的方法是:

    memset(&obj, 0, sizeof obj);
    

    或者如果我们有一个指向对象的指针:

    memset(ptr, 0, sizeof *ptr);
    

    您的表单恰好适用于 C 风格的数组,因为 A 会衰减为指针,但 sizeof A 不会衰减。但是对于非数组,您将得到大小不匹配(或完全错误)。坚持使用两种规范形式中的一种可以避免大小不匹配。


    std::array 不需要实现为 C 样式的数组,因此在其上使用 memset 是不合适的。如果您正在创建数组,您可以简单地编写:

    array<int,5> A = {};
    

    如果您稍后需要重置阵列,则可以使用:

    A.fill(0);
    

    【讨论】:

    • std::array 是“POD”还是标准布局,如果是,那么它应该是“memsettable”吗?见stackoverflow.com/questions/3674247/…
    • −1 “std::array 不需要实现为 C 样式数组”不正确。
    • 附加信息:C++14 §23.3.2.1/1 “array 的元素是连续存储的,这意味着如果aarray&lt;T, N&gt;,那么它遵循身份@ 987654334@ 为所有0 &lt;= n &lt; N"
    • 第四行 *ptr 的大小应该被 ptr 的大小替换
    • @DeepakY4-YrBTechComputerS 不应该
    猜你喜欢
    • 1970-01-01
    • 2021-07-11
    • 2012-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    • 2011-11-04
    相关资源
    最近更新 更多