我得到了这个奇怪的错误:
MyView:OnInitialUpdate()
{
int* my_int;
*(my_int) = 1;
AfxBeginThread(MyThread,my_int);
}
UINT MyThread(LPVOID param)
{
int* my_int = reinterpret_cast<int*>(param);
message(*(my_int));
return 0;
}
void message(int value)
{
CString txt;
txt.Format(_T("%d"),value);
AfxMessageBox(txt);
}
消息框输出为4250636。
现在,如果我在将值传递给线程之前添加另一个消息框:
MyView:OnInitialUpdate()
{
int* my_int;
*(my_int) = 1;
message(*(my_int));
AfxBeginThread(MyThread,my_int);
}
两个消息框输出均为1.
答案 0 :(得分:2)
int* my_int;
*(my_int) = 1;
这是未定义的行为。您没有初始化my_int
,因此您要取消引用无效指针。
而是在x
班级中创建成员MyView
,然后更改为:
int* my_int = &x;
答案 1 :(得分:1)
这个
int* my_int;
定义一个指向某个整数的指针而不用实际的整数地址初始化它,因此它指向内存中的某些 随机地址 。 这个
*(my_int) = 1;
然后将值写入此随机地址。
正式地,这会调用可怕的 未定义的行为 。之后,所有赌注都已关闭。即使您的计算机因此而爆炸,您的编译器也会符合标准。
但是,还有更多内容:由于您将该指针传递给某个要异步执行的函数,因此只要您的其他线程尝试,您需要确保指针引用的对象是“活着的”访问它。基本上,唯一的方法是使其全局,静态或动态分配
但是,考虑到你的代码,我认为没有理由你需要传递一个实际的指针。通过reinterpret_cast<LPVOID>(1)
应该这样做。
答案 2 :(得分:0)
以上两种说法都是正确的,但另一种说法是:
*(my_int) = 1
表示:设置my_int指向1的内容 - 但my_int尚未指向任何内容 - 繁荣。
答案 3 :(得分:0)
你可以使用
AfxBeginThread(..., reinterpret_cast<LPVOID>(static_cast<INT_PTR>(input)));
在你的线程函数中
int my_int = static_cast<int>(reinterpret_cast<INT_PTR>(rawInput));
这也适用于枚举而不是 int
。