将 memset 与未初始化的变量一起使用
Using memset with uninitialized variables
这是没有未定义行为的有效 C 代码吗?
int main(){
int a;
memset(&a, 5, sizeof(int));
return a;
}
我假设这等同于 int a = 5
。
我想知道在上面的例子中仅仅声明一个变量(而不定义它)是否足以将它放入堆栈。
来自C标准(7.23.6.1 memset函数)
2 The memset function copies the value of c (converted to an unsigned
char) into each of the first n characters of the object pointed to by
s.
所以这个电话
memset(&a, 5, sizeof(int));
不会将变量 a
设置为等于 5
。在内部变量看起来像
0x05050505
这是一个演示程序
#include <stdio.h>
#include <string.h>
int main(void)
{
int a;
memset( &a, 5, sizeof( int ) );
printf( "%#x\n", ( unsigned )a );
return 0;
}
它的输出是
0x5050505
您应该谨慎使用带有整数的函数 memset
,因为它通常会产生陷阱值。此外,结果取决于从 MSB 或 LSB 开始存储整数的内部方式。
P.S。您在没有链接的块范围内声明了一个变量。它也是一个具有自动存储持续时间的变量定义。由于变量未明确初始化,因此它具有不确定的值。您可以应用运算符&
的地址来获取定义变量的内存范围的地址。
Is this valid C code without undefined behaviour?
是——一旦在给定范围内声明了 a
变量(如函数或其他 { ... }
分隔块),获取其地址并使用该地址访问变量是有效的地址 在该范围内 (就像您的 memset
调用一样)。在该作用域结束时尝试使用该地址(即不再是'active')将导致未定义的行为;比如下面是UB:
int main()
{
int* p;
{ // New scope ...
int a;
p = &a; // Pointer to "a" is valid HERE
} // The scope of "a" (and its 'lifetime') ends here
memset(p, 5, sizeof(int)); // INVALID: "p" now points to a dead (invalid) variable
}
但是,您的代码示例中有一个重要警告……
I'm assuming this is equal to just doing int a = 5.
有问题:它将 5
分配给 a
变量的 每个组件字节 ,所以它正在这样做(假设一个 4 字节 int
):
int a = 0x05050505;
与以下相同:
int a = 84215045;
这不是未定义的行为。问题是它不是你所期望的。
结果
memset(&a, 5, sizeof(int));
包括设置 5
整数 a
的四个字节中的每一个。
这是没有未定义行为的有效 C 代码吗?
int main(){
int a;
memset(&a, 5, sizeof(int));
return a;
}
我假设这等同于 int a = 5
。
我想知道在上面的例子中仅仅声明一个变量(而不定义它)是否足以将它放入堆栈。
来自C标准(7.23.6.1 memset函数)
2 The memset function copies the value of c (converted to an unsigned char) into each of the first n characters of the object pointed to by s.
所以这个电话
memset(&a, 5, sizeof(int));
不会将变量 a
设置为等于 5
。在内部变量看起来像
0x05050505
这是一个演示程序
#include <stdio.h>
#include <string.h>
int main(void)
{
int a;
memset( &a, 5, sizeof( int ) );
printf( "%#x\n", ( unsigned )a );
return 0;
}
它的输出是
0x5050505
您应该谨慎使用带有整数的函数 memset
,因为它通常会产生陷阱值。此外,结果取决于从 MSB 或 LSB 开始存储整数的内部方式。
P.S。您在没有链接的块范围内声明了一个变量。它也是一个具有自动存储持续时间的变量定义。由于变量未明确初始化,因此它具有不确定的值。您可以应用运算符&
的地址来获取定义变量的内存范围的地址。
Is this valid C code without undefined behaviour?
是——一旦在给定范围内声明了 a
变量(如函数或其他 { ... }
分隔块),获取其地址并使用该地址访问变量是有效的地址 在该范围内 (就像您的 memset
调用一样)。在该作用域结束时尝试使用该地址(即不再是'active')将导致未定义的行为;比如下面是UB:
int main()
{
int* p;
{ // New scope ...
int a;
p = &a; // Pointer to "a" is valid HERE
} // The scope of "a" (and its 'lifetime') ends here
memset(p, 5, sizeof(int)); // INVALID: "p" now points to a dead (invalid) variable
}
但是,您的代码示例中有一个重要警告……
I'm assuming this is equal to just doing int a = 5.
有问题:它将 5
分配给 a
变量的 每个组件字节 ,所以它正在这样做(假设一个 4 字节 int
):
int a = 0x05050505;
与以下相同:
int a = 84215045;
这不是未定义的行为。问题是它不是你所期望的。
结果
memset(&a, 5, sizeof(int));
包括设置 5
整数 a
的四个字节中的每一个。