我有以下代码。
#include<stdio.h>
void func(size_t *ptr)
{
printf("Before *ptr = %d &ptr = %p\n",*ptr, &ptr);
unsigned int len = 100;
*ptr = len;
printf("After *ptr = %d &ptr = %p\n",*ptr, &ptr);
}
void main()
{
int var = 10;
printf("Before var = %d &var = %p\n",var, &var);
func((size_t *)&var);
printf("After var = %d &var = %p\n",var, &var);
return;
}
此代码在 32 位环境中运行良好。 我正在将应用程序迁移到 64 位,在这种情况下,代码会生成一个核心转储。它在少数在线编译器(例如代码 codepad.org)中运行良好,但在 programiz.
中崩溃我知道在 64 位环境中 size_t 大小为 8 字节,但在 32 位环境中为 4 字节。 所以我设法通过更改以下行来解决这个问题。
size_t var = 10;
所以我的问题是,将较小数据大小(例如 int)的指针分配给较高数据大小是错误的吗?(例如 long/size_t)
在这种情况下导致问题的原因是什么?
迁移到 64 位环境时,与指针相关的其他事项还有哪些?
当 ptr 指针传递给 func() 时,它被转换为一个 size_t*。但是,&ptr 仍然是指向 size_t* 的指针,而不是指向 int 的指针(这就是 var)。在 32 位环境中,sizeof(size_t*) 是 4 个字节,因此当打印 &ptr 时,它会打印出正确的值。但是在64位环境下,sizeof(size_t*)是8个字节,所以在打印&ptr的时候,会打印出错误的值,导致printf()函数读取到ptr变量范围之外的内存,结果在未定义的行为和潜在的崩溃中。