memset这个函数的详细,要求有相应的示例代码和说明

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了memset这个函数的详细,要求有相应的示例代码和说明相关的知识,希望对你有一定的参考价值。

memset(str,0,80)是用0来初始化以地址str开始的80个连续单元..
memset函数具体的用法是:
memset() 函数常用于内存空间初始化。如: char str[100]; memset(str,0,100); memset用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为‘ ’或‘\0’;例:char a[100];memset(a, '\0', sizeof(a)); memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;例:char a[100],b[50]; memcpy(b, a, sizeof(b));注意如用sizeof(a),会造成b的内存地址溢出。 strcpy就只能拷贝字符串了,它遇到'\0'就结束拷贝;例:char a[100],b[50];strcpy(a,b);如用strcpy(b,a),要注意a中的字符串长度(第一个‘\0’之前)是否超过50位,如超过,则会造成b的内存地址溢出。

参考资料:回答者:fyg0203jsj - 助理 二级 3-29 13:32

参考技术A void *memset( void *dest, int c, size_t count );
dest是一个地址,c是0-255之间的值,count是要写的字节数。
这个函数的作用就是将dest到dest+count-1这段内存空间中每个字节都写成c。

下面这个例子是我从MSDN里拷的:

Example

/* MEMSET.C: This program uses memset to
* set the first four bytes of buffer to "*".
*/

#include <memory.h>
#include <stdio.h>

void main( void )

char buffer[] = "This is a test of the memset function";

printf( "Before: %s\n", buffer );
memset( buffer, '*', 4 );
printf( "After: %s\n", buffer );


Output

Before: This is a test of the memset function
After: **** is a test of the memset function

解析主机地址的程序中的 Memset 函数

【中文标题】解析主机地址的程序中的 Memset 函数【英文标题】:Memset function in programm that resolves host adresses 【发布时间】:2021-03-28 10:18:48 【问题描述】:

首先,我了解代码(见文章末尾)的一般作用,我不想要一个全面的解释。

我不明白的是这行特定的代码: memset(&hints, 0, sizeof(struct addrinfo));

到目前为止,我得到的是 memset() 是一个函数来填充它指向的字符串。

它有三个参数,第一个是指向字符串的指针,第二个是要设置的值,第三个是要设置的值的字节数。

在这种情况下,要填充的值是 &hints,这将是变量提示的地址。应该设置的值是 0,所以它用零填充。最后填充到 struct addrinfo 的大小。

所以在这种情况下,memset() 为变量提示生成结构体大小的零。我做对了吗?

如果是,为什么在我的示例中需要这样做?

#include <stdlib.h>/* EXIT_SUCCESS */
#include <stdio.h>/* printf */
#include <string.h>/* memset() */
#include <errno.h>/* int errno */
#include <sys/types.h>/* socket defines */
#include <sys/socket.h>/* socket() */
#include <netdb.h>/* getaddrinfo() */
#define ECHO_PORT "7"

int main (int argc, char* argv[])
if (argc != 2) 
printf ("Usage: %s HOSTNAME\n", argv[0]);
exit(EXIT_FAILURE);


/* Resolve host addresses: */

struct addrinfo hints;
struct addrinfo* result, *rp;

memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;/* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_STREAM;/* Stream socket */
hints.ai_flags = 0;
hints.ai_protocol = 0;/* Any protocol */

int err = getaddrinfo(argv[1], ECHO_PORT, &hints, &result);

/* Handle potential error: */

if (err) 
printf("Error: getaddrinfo: %s\n", gai_strerror(err));
exit(EXIT_FAILURE);


/* Print names found: */

printf("Addresses for %s:\n", argv[1]);
for (rp = result; rp != NULL; rp = rp->ai_next) 
int af = rp->ai_family;
char* address = NULL;
int ok;

if (AF_INET == rp->ai_family) 
uint8_t in_addr =((struct sockaddr_in*)rp->ai_addr)->sin_addr.s_addr;
address = malloc(INET_ADDRSTRLEN);
ok = inet_ntop(af, &in_addr, address, INET_ADDRSTRLEN);


if (AF_INET6 == rp->ai_family) 
char* in6_addr =((struct sockaddr_in6*)rp->ai_addr)->sin6_addr.s6_addr;
address = malloc(INET6_ADDRSTRLEN);
ok = inet_ntop(af, in6_addr, address, INET6_ADDRSTRLEN);


if (ok) 
printf("%s\n", address);

else 
perror("inet_ntop");


free(address);


freeaddrinfo(result);

return EXIT_SUCCESS;


【问题讨论】:

你知道未初始化的变量默认值是不确定的吗?此处 memset 的重点是确保对象没有,因此任何可能未设置的字段都具有零值 - 而不是读取未定义行为的垃圾。如果这 4 个分配覆盖了结构中的所有字段,那么从技术上讲,memset 是多余的 - 但这可能是一种很好的做法,因为它可能会在以后获得更多字段,然后如果结构没有先清零,然后有人会爆炸,那么事情可能会爆炸试图读取未初始化的成员。顺便说一句,C++ 有更好的方法来做到这一点 请不要同时标记 C 和 C++,除非问题涉及两种语言之间的交互或差异。对于 C 和 C++,问题的答案可能不同,这可能会令人困惑。要针对 C 和 C++ 提出相同的问题,请输入两个单独的问题。由于您的代码似乎是 C 代码,因此我将删除 C++ 标记。如果您使用的是 C++ 而不是 C,那么您可以更改标签。 @EricPostpischil 我同意 - 我不得不改变我的 C++ 答案:-) @underscore_d 感谢您提供背景信息。我不知道。 @EricPostpischil 谢谢你的提示。我会在以后的帖子中考虑这一点 【参考方案1】:

是的,你理解正确。

在下面的代码中需要它,因为在

struct addrinfo hints;

hints 未初始化,程序员希望确保所有字段都归零。

一个更简单的解决方案是直接初始化它:

addrinfo hints; // C++11 and later

struct addrinfo hints = 0; /* C and C++ */

并跳过memset

另一个选择是使用designated initializers(C99 和 C++20)用正确的值初始化它。在 C 中,您可以乱序指定字段,但在 C++ 中则不行,因此此顺序适用于两者:

struct addrinfo hints =   /* "struct" not needed in C++ */
    .ai_flags    = 0,
    .ai_family   = AF_UNSPEC,
    .ai_socktype = SOCK_STREAM,
    /* .ai_protocol and the rest will be zeroed */
;

对于没有指定初始化器的旧标准:

struct addrinfo hints = 
    0,
    AF_UNSPEC,
    SOCK_STREAM
;

【讨论】:

C 版本的初始化程序至少需要一个值。 0 是惯用的。我不确定 C++ 是否接受。 @JohnBollinger C++ 也接受了,所以我会补充一下,谢谢。 请注意, 仅适用于 C++11 及更高版本,但 0 将适用于所有 C++ 版本。 @RemyLebeau 哦,是的,最好也记下这一点,谢谢!【参考方案2】:

您说得对,这里使用了memsethints 的所有字节设置为零。

这样做是为了使以后未显式设置的任何字段都具有值 0。因为 hints 未初始化,其字段具有不确定的值,因此这样做会将所有字段设置为 0。如果您查看定义struct addrinfo:

       struct addrinfo 
           int              ai_flags;
           int              ai_family;
           int              ai_socktype;
           int              ai_protocol;
           socklen_t        ai_addrlen;
           struct sockaddr *ai_addr;
           char            *ai_canonname;
           struct addrinfo *ai_next;
       ;

您可以看到该程序仅显式设置了前 4 个字段。对memset 的调用首先会处理其余的事情。

【讨论】:

【参考方案3】:

是的,你的理解基本正确。代码只是用0x00 字节填充整个hints 变量,然后将其传递给getaddrinfo()。这是将hints 初始化为默认状态所必需的,这很重要,因为addrinfo 包含用于控制getaddrinfo() 行为的标志和内存指针。所以你不能只让hints 处于未初始化状态,它会包含随机垃圾,会导致未定义的行为、混淆getaddrinfo() 和/或什至导致内存损坏、崩溃等.

使用memset() 是一种在一次快速操作中将hints 的所有字段初始化为零的快速方法,而不是单独初始化每个字段。这样,您可以专注于为您真正感兴趣的字段分配值。

初始化hints 的更简单方法是:

struct addrinfo hints = 0;

这将 value-initialize 第一个字段 (ai_flags) 为 0,而 default-initialize 其余字段为其默认值,在本例中为也是零。

【讨论】:

当然,“旧编译器”不仅包括那些实现旧版本 C++ 的编译器,还包括所有不提供初始化器语法扩展的 C 编译器。 问题现在被标记为 C。= 不是 any 语言的首选初始化方式。

以上是关于memset这个函数的详细,要求有相应的示例代码和说明的主要内容,如果未能解决你的问题,请参考以下文章

c语言memset()函数

与memset函数等效的Linux内核是什么?

c++这个memset()函数有啥用? memset(啥意思,啥意思,啥意思);

C语言 memset函数

Matlab数字图像处理,要求详细解释代码,每个函数都要解释.这个是对图像求幅值谱和相位谱,并对其进行重构.

带导航的 Ipad 多个详细视图