如何解决使用带有未初始化变量的 memset
这是没有未定义行为的有效 C 代码吗?
int main(){
int a;
memset(&a,5,sizeof(int));
return a;
}
我假设这等于只执行 int a = 5
。
我试图理解在上面的例子中仅仅声明一个变量(没有定义它)是否足以将它放在堆栈中。
解决方法
这是没有未定义行为的有效 C 代码吗?
是 - 一旦 a
变量在给定范围内声明(如函数或其他 { ... }
分隔块),获取其地址并使用该地址访问变量是有效的 在该范围内(就像您的 memset
调用一样)。 当该作用域结束(即不再“活动”)时尝试使用该地址将导致未定义的行为;例如,以下是 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
}
但是,您的代码示例中有一个主要警告……
我假设这等于做 int a = 5。
有问题:它正在将 5
分配给 a
变量的每个组件字节,所以它这样做(假设是 4 字节的 int
) :
int a = 0x05050505;
与以下相同:
int a = 84215045;
,
来自 C 标准(7.23.6.1 memset 函数)
2 memset 函数复制 c 的值(转换为无符号数 char) 指向的对象的前 n 个字符中的每一个 s.
所以这个电话
memset(&a,sizeof(int));
不会将变量 a
设置为等于 5
。在内部变量看起来像
0x05050505
这是一个演示程序
#include <stdio.h>
#include <string.h>
int main(void)
{
int a;
memset( &a,sizeof( int ) );
printf( "%#x\n",( unsigned )a );
return 0;
}
它的输出是
0x5050505
您应该谨慎地将函数 memset
与整数一起使用,因为它通常会产生陷阱值。此外,结果取决于内部整数如何从 MSB 或 LSB 开始存储。
附言您在没有链接的块范围内声明了一个变量。它也是一个具有自动存储期限的变量定义。由于变量未显式初始化,因此它具有不确定的值。您可以应用运算符&
的地址来获取定义变量的内存范围的地址。
这不是未定义的行为。问题是它不是你所期望的。
结果
memset(&a,sizeof(int));
包括将整数 5
的四个字节中的每一个设置为 a
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。