静态数组上的 memset

Posted

技术标签:

【中文标题】静态数组上的 memset【英文标题】:memset on static array 【发布时间】:2013-03-17 20:32:37 【问题描述】:

当您必须设置静态数组的元素时,我对将什么作为第一个参数传递给 memset 感到有些困惑。我一直在搜索,但找不到某些特定问题的答案。

如果我有一个数组声明为:

char arr[10];

我已经看到这两个调用是有效的并且产生相同的效果:

memset( arr, 0, 10);
memset( &arr, 0, 10);

我的具体问题是:

1- 为什么它们对 arr 有相同的影响?

2- 这些调用有什么不同?

3- 哪一个会被认为是正确的?

谢谢!

【问题讨论】:

将它们全部设置为零的正确方法:char arr[10] = ; 【参考方案1】:

存储时长与它无关;数组就是数组。这个表达式:

&arr

产生一个char (*)[10],即一个指向char数组的指针,该数组有10个元素。但是,当arr 被传递给这样的函数时:

memset(arr, 0, 10);

它降级为指向第一个元素的指针,即char*。这些不是一回事。 “正确”(惯用的)调用是:

memset(arr, 0, 10);

但是,在这种情况下,它们在传递给memset 时都转换为void*,并在函数中解释为unsigned char*。由于它们都指向同一个地方,因此会产生相同的结果。

但是,重要的是要意识到,在处理真正的各自类型(即,不是 void*)时,指向数组的指针与指向数组的第一个元素。

例如,增加char (*)[10] 将增加指针sizeof(char[10]) 字节,而增加char* 将仅增加一个字节。

【讨论】:

更正一处:and interpreted in the function as a char*应该改为unsigned char*【参考方案2】:

为什么它们对 arr 有相同的影响?这些调用有什么不同?

因为数组的地址与其第一个元素的地址相同(数组在传递给函数时会衰减为指向其第一个元素的指针),只是它们具有不同的类型。 arr 具有 char[10] 类型,当传递给函数时会衰减为 char *。相比之下,&arr 的类型 char (*)[10] 在作为函数参数传递时不会改变。

哪一个会被认为是正确的?

只要函数不期望特定类型,i。 e.它接受void *,任何一个都可以。但是,如果被调用的函数期望指定其中一种类型,则不应使用另一种类型,因为这样您的程序将出现格式错误并调用未定义的行为。

【讨论】:

使用memset( arr, 0, 10);不是更好吗?如果由于某种原因将数组的声明更改为char *arr = new char[10],它仍然有效。 @user502144 我们不是在谈论“当它改变时”的情况。或者,更准确地说,我在上一部分中已经提到了当两者有效时。【参考方案3】:

1- 为什么它们对 arr 有相同的影响?

它们都包含相同的值,即数组开头的地址。

2- 这些调用有什么不同?

arr 衰减为指向 char 的指针,即 char*(当您将数组名称传递给函数时会发生这种转换),&arr 是指向 数组 的指针char,即char (*)[]

3- 哪一个会被认为是正确的?

我会使用arrmemset 接受 void* 这就是两者都起作用的原因。

另外,请注意char arr[10] = ; 可用于对数组进行零初始化。

【讨论】:

小心 - arr 不是指向 char 的指针,但它可以衰减为一个。 @DrewDormann:谢谢,当你快速打字时很难准确(改变措辞)。

以上是关于静态数组上的 memset的主要内容,如果未能解决你的问题,请参考以下文章

库中静态分配的 zlib 字节数组上的 memset 使 Objective-C++ 程序崩溃

C/C++ 中非常大的静态数组的算术运算

C语言中malloc和静态数组最多能开到多大呢

数据结构_2

静态链表(C++实现)

[bzoj1935][Shoi2007]Tree 园丁的烦恼 _树状数组