【问题标题】:How do I do a memset for a pointer to an array?如何为指向数组的指针执行 memset?
【发布时间】:2012-09-24 05:06:58
【问题描述】:

如何为指向数组的指针创建 memset?

int (*p)[2];

p=(int(*))malloc(sizeof(*p)*100);

memset(p,0,sizeof(*p)*100);

这个分配正确吗?

【问题讨论】:

  • Do not cast the result of malloc,你试过了吗?是什么让您认为它可能不正确?
  • 您需要澄清一下,您需要 C 还是 C++。因为对于 C++,所有这些都不需要
  • 我的困惑是我应该写 memset(p,0,sizeof(*p)*​​100);或 memset(p,0,sizeof(int[2])*100);
  • 我不太明白你想要做什么......我的意思是,你的目标是什么(从你的代码中不清楚)。
  • 总是使用sizeof(*your_variable),这样你就不会弄错了

标签: c++ c dynamic memset


【解决方案1】:

你可以使用calloc

calloc 将替换 mallocmemset

p = calloc(100, sizeof (*p));

【讨论】:

    【解决方案2】:

    我会总结很多答案(尽管我忽略了一些风格变体以支持我自己的喜好)。

    在 C 中:

    如何使用malloc:

    int (*p)[2] = malloc(100 * sizeof(*p));
    

    如何使用memset:

    memset(p, 0, 100 * sizeof(*p));
    

    如何在一个语句中做到这两点:

    int (*p)[2] = calloc(100, sizeof(*p));
    

    在 C++ 中,除了您需要转换 malloccalloc 的结果:static_cast<int(*)[2]>(std::malloc(100 * sizeof(*p)) 之外,也是可以的。

    但是,C++ 提供了其他分配方式:

    int (*p)[2] = new int[100][2](); // like calloc.
    delete[] p; // *not* delete p
    

    C++ 还提供了vector,这通常很好,但不幸的是,您无法创建 C 样式数组的向量。在 C++03 中,您可以这样解决:

    struct my_array {
        int data[2];
    };
    
    std::vector<my_array> p(100);
    // no need to free/delete anything
    

    我认为这不会将元素归零,尽管我可能错了。如果我是对的,那么你需要归零:

    my_array initvalue = {0};
    std::vector<my_array> p(100, initvalue);
    

    另一种表示 2 个整数的方式:

    std::vector<std::pair<int,int> > p(100);
    

    如果你可以使用 Boost:

    std::vector<boost::array<int, 2> > p(100);
    

    在 C++11 中:

    std::vector<std::array<int, 2>> p(100);
    

    我按照它们通常的好坏程度的递增顺序列出了这些,因此请使用不受您正在工作的任何约束条件阻碍的最后一个。例如,如果您希望获取一个指向内部 arrays-of-2-int 的第一个元素的指针,并将其递增以获取指向第二个元素的指针,则 std::pair 不可用,因为它不能保证行得通。

    【讨论】:

    • 默认情况下结构是否包含垃圾或零当然取决于它声明的范围(全局/静态与自动)。在 C++ 中,最好为结构添加一个构造函数,这样您就不需要依赖显式初始化。
    • @Lundin:我几乎添加了一个构造函数,但是(a)我不想不必要地使它成为非 POD,并且(b)仅仅因为我想要这个向量归零并不必然意味着我希望类的每个实例都被归零。我的基本困惑是我不记得临时 my_array() 是默认初始化还是零初始化。它既不是全局的也不是自动的!
    • 它将运行默认构造函数,它什么也不做。因此,除非您添加构造函数,否则数据将是垃圾。你总是可以添加一个像my_array(int arr[2] = NULL) 这样的零初始化条件。
    【解决方案3】:

    优雅的方式:

    typedef int int_arr_2[2];
    
    int_arr_2* p;
    
    p = malloc(sizeof(int_arr_2)*100);
    memset(p,0,sizeof(int_arr_2)*100);
    

    最好的办法:

    typedef int int_arr_2[2];
    
    int_arr_2* p;
    
    p = calloc(100, sizeof(int_arr_2));
    

    calloc 与 malloc 不同,它保证所有字节都设置为零。

    【讨论】:

    • 我对 calloc 的看法是 +1,-1 表示 sizeof(int_arr_2)sizeof(*p) 更优雅。但它的 +1 比 -1 大,所以我很容易被说服 ;-)
    • @SteveJessop 代码很优雅,原因如下:程序员不可能意外地获取 sizeof(指针本身)。特别是,在 bool custom_allocate (int** array); 这种不太常见的情况下,您肯定会弄错,其中分配的数据通过参数传递给 main。要做到这一点,您需要写malloc(sizeof(**array))。除此之外,对于不习惯数组指针的普通 C 程序员来说,typedef 语法也更容易和更直观地阅读。
    • 我不认为我一定会弄错。我会写*array = malloc(number * sizeof(**array))。或some_function()-&gt;member = malloc(number * sizeof(*(some_function()-&gt;member)))。这不是一个复杂的规则。但我的意思是我可以确信这是一个很好的答案,而不是我可以确信我更喜欢你写大小的方式。我不能相信这一点,因为你错了 :-) 我不介意指向数组的指针的 typedef,不过,这是另一个优点。
    • @SteveJessop 但是,从您在本网站上与 C 相关的帖子的质量来看,我认为您不属于“普通 C 程序员”类别 :) 编写的代码甚至可以让菜鸟程序员理解和维护,比编写可以由拥有几十年经验的 C 大师理解和维护的代码更具挑战性。
    • 奉承会带你到任何地方。我完全同意 typedef 帮助新手:指向数组的语法有时令人费解。不过,我真的不同意,重复类型有助于新手。在您的版本中,只有一种类型是正确的,程序员必须弄清楚它是什么,也许不时更新它。在我的版本中,它们表示“LHS 指向的类型”,它总是是正确的类型(否则你不会分配给它),他们通过添加一个 @ 来做到这一点987654329@.
    【解决方案4】:

    memset() 行是正确的。

    为C你don't need malloc casting.
    在 C++ 中,如果您仍想这样做,类型转换应为:

    p = (int(*)[2]) malloc(sizeof(*p)*100);  // or `static_cast<...>
      // ^^^^^^^^^
    

    但我建议您更改使用 std::vector 的方法。更清洁、更好和“半自动”:

    std::vector<int*> vi(100);  // or std::vector vi(100, nullptr);
    

    使用原始指针的另一种方法是使用new[]

    int **p = new[100]();  // allocates and sets to 0
    

    但您必须稍后通过使用 delete[] 解除分配来管理此内存

    【讨论】:

    • 在 C++ 中,强制转换是一种很好的风格。在 C 中,强制转换是危险的,并且会产生严重的错误。它们是不同的语言。这就是为什么您一次只能使用一种编程语言进行编程的原因 :)
    • @Lundin:我认为iammilind 的观点是,在C++ 中,malloc 不是强制性的。因此“你可以拥有这个”,但他的建议是你不要:-)
    • 在 C++ 中,您将使用 new,因此不需要强制转换。只需在 new 表达式的末尾添加一个 () 即可有效地将所有分配的值设置为 0。
    • @JamesKanze,理想情况下,我仅在有特定编程要求(即复制成本高昂或多线程环境)时才使用new/new[]。始终建议使用std::vector,它在内部执行此操作并负责删除内存。
    • @iammilind 好点。 std::vector&lt;int&gt; 在这里会更好。
    【解决方案5】:

    在 C(不是 C++)中你会这样做

    int (*p)[2] = malloc(sizeof(*p)*100);
    
    memset(*p,0,sizeof(*p)*100);
    

    也就是说,变量可以用表达式初始化,malloc 不需要(也不应该有)强制转换。那么*p 是您的数组类型的“左值”,当传递给memset 时会衰减为指针。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-19
      相关资源
      最近更新 更多