无效* 转换获得意外输出

void* casting get unexpected output

本文关键字:意外 输出 转换 无效      更新时间:2023-10-16
struct mystruct{
int* x;
float *y;
string *z;
mystruct(int* a,float* b, string *c): x(a), y(b), z(c){}
};
void* create(){
int a = 1;
float b = 2.2;
string c = "aaa";
mystruct x(&a, &b, &c);
void* p = &x;
return p;
}
void print(void *p){
mystruct* p1 = static_cast<mystruct*>(p);
cout << *p1->x  << " " << *p1->y << " "<<*p1->z<< endl;
}
int main(){
cout << sizeof(mystruct) << endl;
void* p1 =  create();
print(p1);
return 0;
}

代码的输出如下:24 1 2.76648e+19 \203\304 ]\303ffff.\204UH\211\345H\201\354\220H\211}\270H\211. 我想是:24 1 2.2 aaa

我想 void* 指针投射有问题,但我不知道为什么。有人可以帮忙吗?

你用这个创建未定义的行为:

void* create(){
int a = 1;
float b = 2.2;
string c = "aaa";
mystruct x(&a, &b, &c);
void* p = &x;
return p;
}

在这里,您可以使用指向自动存储范围(也称为局部变量(中的对象的指针初始化mystructcreate。这些对象在返回create的那一刻就不复存在,因此指针变得无效。此外,您还将返回一个指向create函数内mystruct自动存储对象的指针。所以这是在未定义的行为之上调用未定义的行为。

编辑 这是一个建议的解决方案:

停止在结构中使用指针。无论如何,传递指向intfloat的指针是没有意义的,因为指针总是比这些指针。如果将指针或指针传递给函数,则两者都将通过复制值来传递,但使用指针时,会有一个额外的间接步骤。如果要使用指向数值类型的指针传递函数可以更改值的"引用",则传递到数值类型的指针是有意义的。

将指针传递给结构也是有意义的,这样就不必复制整个结构。

所以我建议你把指针从整体上去掉。您显然还不了解它们是如何工作的,对于您那里的特定任务,无论如何它们都是错误的工具。