【问题标题】:Why isn't memset assigning 1? [duplicate]为什么 memset 不分配 1? [复制]
【发布时间】:2016-03-07 08:26:05
【问题描述】:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;

int color[1001][1001];

int main() {
    int i, j;
    memset(color, 1, sizeof(color[0][0]) * 2 * 2);
    for(i = 0; i < 4; i++) {
        for(j = 0; j < 4; j++) {
            printf("%d ", color[i][j]);
        }
        printf("\n");
    }
    printf("\n");

    return 0;
}

输出:

16843009 16843009 16843009 16843009 
0 0 0 0 
0 0 0 0 
0 0 0 0 

为什么不分配 1?为什么它不打印 1 而不是 16843009 ?如何分配整数 1?

但是如果我写memset(color, 0, sizeof(color[0][0]) * 2 * 2); 那么输出:

0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 

这是为什么?

任何答案都将受到高度赞赏。提前致谢。

【问题讨论】:

  • 从手册页剪切'n'paste - “memset - 用常量字节填充内存”
  • 因为您没有阅读您正在使用的函数的文档。 ;-)

标签: c++ c memset


【解决方案1】:

因为memset每个字节 设置为1

所以如果int 是四个字节(32 位,最常见的是),那么您将每个元素设置为0x01010101

阅读更多in this memset reference page


对于更 C++-ish 的解决方案,我建议使用std::fill

std::fill(&color[0][0], &color[0][0] + sizeof(color) / sizeof(color[0][0]), 1);

这会将所有元素设置为1


第三种选择是改用std::array 及其fill 成员函数:

std::array<std::array<int, 1001>, 1001> color;
...
for (auto& inner : color)
{
    inner.fill(1);
}

【讨论】:

  • 这是对填充的错误使用。作为第一个参数传递的迭代器必须通过解引用它来使其值可写,但是解引用 color 会给出另一个数组。这会导致编译错误。此外,color + sizeof(color)/sizeof(color[0][0]) 通过形成越界指针会导致未定义的行为。
  • @M.M 我一直认为最后一个元素后面的指针是明确定义的,只是取消引用它不是。迭代器以这种方式工作,AFAIK。
  • @M.M 确认一下,应该是std::fill(&amp;color[0][0], &amp;color[0][0] + sizeof(color) / sizeof(color[0][0]), 1);吧?
  • @cad ,是的,明确允许形成指向最后一个元素的指针。
  • @cad 是的。 sizeof(color)/sizeof(color[0]) 会导致这样的指针。然而,实际代码除以比sizeof(color[0]) 更小的数量。
【解决方案2】:

Manpage

#include <string.h>
void *memset(void *s, int c, size_t n)

memset() 函数用常量字节c 填充s 指向的内存区域的第一个n 字节

因此,memset不能用1来初始化int数组,因为如果int用4个字节表示,那么它将用1初始化每个字节。
@987654332 @ 等价于 0x01010101。 4 个字节中的每一个都用01 初始化。
使用memsetint 的数组只能用0-1 初始化,因为0-1 都在二进制补码中分别具有01 的所有位表示而不管int数据类型的大小。

【讨论】:

  • 但是如果我写memset(color, 0, sizeof(color[0][0]) * 2 * 2); 那么输出为零。为什么?我已经编辑了原始问题。
  • @shibly 因为所有单个字节都为零的整数也是该整数的零值。 (并且由于您的数组是在文件范围内声明的(一个“全局”变量),因此整个数组无论如何都会用零值初始化)
  • @nos, 0x00000000 = 空字符(ascii),不是吗?
  • @shibly 如果您将该值解释为 ascii,则可以。虽然通常你会使用 char 来表示 ascii 值。
  • @shibly;我已经在答案中解释过了。请注意,char 只有1 字节。所以0x00代表一个十六进制的空字符。
【解决方案3】:

memset() 会将指定的值写入范围内的每个字节,因此如果int 的长度为 4 字节,则该值将是0x01010101,而不是1

要分配整数 1,请分配整数 1。

for (i = 0; i < (int)(sizeof(color)/sizeof(*color)); i++) {
    for (j = 0; j < (int)(sizeof(color[i])/sizeof(*color[i])); j++) {
        color[i][j] = 1;
    }
}

【讨论】:

    【解决方案4】:

    memset() 将内存设置为 8 位对齐到您选择的值,即1。但是对于您的数组 color[][],您声明了 32 位数据类型 int,它有四个字节。那么memset() 所做的就是将这四个字节中的每一个都设置为值1

    这也解释了你的结果:16843009d = 0x01010101

    如果你看看你的记忆:

    memset()1:

    //.color[0][0].||..color[0][1]...||..color[0][2]...||..color[0][3]..
    01  01  01  01    01  01  01  01    01  01  01  01    01  01  01  01
    //.color[1][0].||..color[1][1]...||..color[1][2]...||..color[1][3]..
    00  00  00  00    00  00  00  00    00  00  00  00    00  00  00  00
    //.color[2][0].||..color[2][1]...||..color[2][2]...||..color[2][3]..
    00  00  00  00    00  00  00  00    00  00  00  00    00  00  00  00 
    //.color[3][0].||..color[3][1]...||..color[3][2]...||..color[3][3]..
    00  00  00  00    00  00  00  00    00  00  00  00    00  00  00  00 
    

    memset()0:

    //.color[0][0].||..color[0][1]...||..color[0][2]...||..color[0][3]..
    00  00  00  00    00  00  00  00    00  00  00  00    00  00  00  00
    //.color[1][0].||..color[1][1]...||..color[1][2]...||..color[1][3]..
    00  00  00  00    00  00  00  00    00  00  00  00    00  00  00  00
    //.color[2][0].||..color[2][1]...||..color[2][2]...||..color[2][3]..
    00  00  00  00    00  00  00  00    00  00  00  00    00  00  00  00 
    //.color[3][0].||..color[3][1]...||..color[3][2]...||..color[3][3]..
    00  00  00  00    00  00  00  00    00  00  00  00    00  00  00  00 
    

    如果您使用值 0 调用 memset(),那么您将获得 32 位 int value = 0x00000000 = 0d

    注意:

    如果要将整个数组设置为一个值,请使用以下行:
    memset(color, 1, sizeof(color));
    

    那么你的数组如下所示:

    1010101 1010101 1010101 1010101 
    1010101 1010101 1010101 1010101 
    1010101 1010101 1010101 1010101 
    1010101 1010101 1010101 1010101 
    

    查看代码here[^]

    【讨论】:

    • 但是如果我写memset(color, 0, sizeof(color[0][0]) * 2 * 2); 那么输出为零。为什么?我已经编辑了原始问题。
    猜你喜欢
    • 1970-01-01
    • 2021-10-24
    • 1970-01-01
    • 2014-06-15
    • 1970-01-01
    • 1970-01-01
    • 2014-06-02
    • 1970-01-01
    • 2013-10-02
    相关资源
    最近更新 更多