【问题标题】:Memset Definition and useMemset 定义和使用
【发布时间】:2012-10-30 21:34:58
【问题描述】:

函数memset()有什么用处?

定义:将 ptr 指向的内存块的前 num 个字节设置为 指定值(解释为无符号字符)。

这是否意味着它对内存地址中的值进行硬编码?

memset(&serv_addr,0,sizeof(serv_addr) 是我试图理解的示例。

有人可以用非常简单的方式解释一下吗?

【问题讨论】:

  • 多用于初始化结构体和数组。
  • 所以就像说数组[值]?为什么不这样做呢,那么使用 memset 有什么意义呢?
  • 只有在编译时知道value的值(这是C/C++),你才能像array[value]那样做。
  • 因为您可以同时设置结构/数组上的所有字节。您可以使用 for 循环来完成,但 memset 的性能会好很多。

标签: c++ c function


【解决方案1】:

memset()是一个非常快速的版本,操作相对简单:

void* memset(void* b, int c, size_t len) {
    char* p = (char*)b;
    for (size_t i = 0; i != len; ++i) {
        p[i] = c;
    }
    return b;
}

也就是说,memset(b, c, l) 将从地址b 开始的l 字节设置为值c。它只是比上面的实现快得多。

【讨论】:

  • @Neil:好点 - 我是 C++ 人,我意识到我依赖于转换。我将代码更改为 C 和 C++。
  • 按照编码,您的函数具有实现定义的行为,因为c 可能超出了char 类型的范围。您应该将 p 定义为 unsigned char *p = (unsigned char*)b; (仅在 C++ 中需要转换)。
  • @DietmarKühl 为什么它的速度更快?没有循环怎么可能呢?它是否使用操作系统 api 来做到这一点?即便如此,它仍然需要一个循环。
  • @Nik-Lz:编译器知道memset(),不需要对参数做任何分析,很容易生成向量运算。诚然,许多编译器会在优化模式下向量化循环。
【解决方案2】:

memset() 通常用于初始化值。例如考虑以下结构:

struct Size {
    int width;
    int height;
}

如果您像这样在堆栈上创建其中一个:

struct Size someSize;

那么该结构中的值将是未定义的。它们可能是零,它们可能是从上次使用堆栈的那部分时发生的任何值。所以通常你会遵循这条线:

memset(&someSize, 0, sizeof(someSize));

当然也可以用于其他场景,这只是其中之一。只需将其视为一种简单地将一部分内存设置为某个值的方法。

【讨论】:

  • 鉴于询问 memset 的意义是什么的问题,这个答案比接受的一个恕我直言。
【解决方案3】:

memset 是将内存区域设置为 0 的常用方法,无论数据类型如何。可以说memset 不关心数据类型,只是将所有字节设置为零。

恕我直言,在 C++ 中应该尽可能避免使用memset,因为它规避了 C++ 提供的类型安全性,而是应该使用构造函数或初始化作为初始化的手段。在类实例上完成的 memset 也可能会无意中破坏某些东西:

例如

class A
{
public:
  shared_ptr<char*> _p;
};

上述实例上的memset 不会正确地减少引用计数器。

【讨论】:

  • 这个答案应该在列表的前面。在 C++ 中使用 memset 是不安全的。
【解决方案4】:

我猜serv_addr 是一些struct 类型的局部或全局变量-也许是struct sockaddr-(或者也许是class)。

&amp;serv_addr 正在获取该变量的地址。这是一个有效的地址,作为memset 的第一个参数给出。 memset 的第二个参数是用于填充的字节(零字节)。 memset 的最后一个参数是要填充的内存区域的大小(以字节为单位),即您的示例中的 serv_addr 变量的大小。

所以对memset 的调用会清除包含一些struct 的全局或局部变量serv_addr

实际上,GCC 编译器在优化时会为此生成巧妙的代码,通常是展开并内联它(实际上,它通常是内置的,所以 GCC em> 可以为它生成非常聪明的代码)。

【讨论】:

    【解决方案5】:

    只是将内存设置为特定值。

    这里是示例代码。

    Memset(const *p,unit8_t V,unit8_t L) ,这里 P 是指向目标内存的指针,V 是指向目标缓冲区的值,它将被设置为值 V,l 是数据的长度.

    while(L --> 0)
    {
        *p++ = V;
    }
    

    【讨论】:

    • downto to 运算符--&gt; 的好例子,但我对L 参数的类型高度怀疑:unit8_t 应该是size_t
    【解决方案6】:

    memset- 设置内存中的字节数

    剧情简介-

    #include<string.h>
    

    void *memset(void *s,int c,size_t n)

    描述- memset() 函数应将 c(转换为无符号字符)复制到 s 指向的对象的前 n 个字节中。 这里对于上述函数,memset() 应该返回 s 值。

    【讨论】:

    • 这个答案如何为一个有 5 个其他答案的 4 岁帖子增加价值?
    • 我一直在寻找答案,我从另一个来源了解了这个定义。所以认为这对其他正在寻找这个定义的人会有所帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-08
    • 1970-01-01
    • 1970-01-01
    • 2014-06-09
    • 1970-01-01
    • 2020-07-09
    • 2018-06-17
    相关资源
    最近更新 更多