【问题标题】:memset not filling arraymemset 未填充数组
【发布时间】:2009-09-13 21:16:26
【问题描述】:
 u32 iterations = 5;
 u32* ecx = (u32*)malloc(sizeof(u32) * iterations);

 memset(ecx, 0xBAADF00D, sizeof(u32) * iterations);
 printf("%.8X\n", ecx[0]);

 ecx[0] = 0xBAADF00D;
 printf("%.8X\n", ecx[0]);

 free(ecx);

很简单,为什么我的输出如下?

0D0D0D0D
BAADF00D

ps: u32 是 unsigned int 的简单 typedef

编辑:

  • 使用 gcc 4.3.4 编译
  • 包含string.h

【问题讨论】:

    标签: c memset


    【解决方案1】:

    memset 的第二个参数类型为 int,但为 really an unsigned char。 0xBAADF00D 转换为无符号字符(最低有效字节)是 0x0D,所以 memset 用 0x0D 填充内存。

    【讨论】:

    • 哦,这很愚蠢。填充它的最佳方法是什么?只是手动循环它,还是有专门用于处理比 char 更大的类型的函数?
    • @Daniel,它是 silly 因为该例程使用 stosb 汇编命令非常快地设置字节,但它不支持 stosw(字) &stosd(双字)。
    • @Daniel:除非您将其衡量为性能瓶颈,否则编写一个简单的循环是最好的方法。
    • memset 需要 int 的原因是它可以追溯到 ANSI C 之前的日子,当时引入了函数原型。非原型函数的参数被扩大到int / unsigned int,因此为了使memset 的原型ANSI C 定义与旧的非原型定义兼容,它必须采用int
    【解决方案2】:

    memset() 的第二个参数是 char,而不是 int 或 u32。 C 自动将 0xBAADF00D int 截断为 0x0D char 并根据请求设置内存中的每个字符。

    【讨论】:

      【解决方案3】:

      我用 wmemset() 试过了。它似乎工作:

      
      #include <stdlib.h>
      #include <stdio.h>
      #include <inttypes.h>
      #include <wchar.h>
      
      int main(void){
        uint32_t iterations = 5;
        uint32_t *ecx = (uint32_t*)malloc(sizeof(uint32_t) * iterations);
      
        wmemset( (wchar_t*)ecx, 0xBAADF00D, sizeof(uint32_t) * iterations);
        printf("%.8X\n", ecx[0]);
      
        ecx[0] = 0xBAADF00D;
        printf("%.8X\n", ecx[0]);
      
        /* Update: filling the array with memcpy() */
        ecx[0] = 0x11223344;
        memcpy( ecx+1, ecx, sizeof(*ecx) * (iterations-1) );
        printf("memcpy:   %.8X %.8X %.8X %.8X %.8X\n",
                   ecx[0], ecx[1], ecx[2], ecx[3], ecx[4] );
      }
      

      【讨论】:

      • 我认为您被否决的原因是 wmemset 采用宽字符参数(又名 wchar_t),它是 16 位,而不是 32 位。但这很有趣:我从来不知道该函数存在。整洁。
      • 输出是什么? 0D0D0D0D? F00DF00D?
      • 忽略我之前的评论,我认为 wmemset 不适合你,但它是:)
      • @sambowry:我想这取决于实现。它基于底层的整数类型,因此您的编译器可能选择了 int 而不是 short。谷歌搜索了一下,看起来 wchar_t 在 Windows 上通常是 2 个字节,在 Linux/Mac 上是 4 个字节。由于提问者使用的是 gcc,它可能是 Linux,所以这对他有用。不过,它并不是真正的便携。很好的解决方案。 +1
      【解决方案4】:

      memcpy( ecx+1, ecx, ... 的技巧在 Linux 上不起作用。仅复制 1 个字节而不是 iterations-1

      【讨论】:

        猜你喜欢
        • 2021-05-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多