2011-06-15 115 views
0

我得到这个奇怪的错误:奇怪的错误铸造LPVOID为int指针

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

+1

这是否真的编译? MyView是一个goto标签还是一个类名? – 2011-06-15 19:54:04

+0

这只是一个简单的例子,但我想下面的其他人发现我的问题的原因。 – Smash 2011-06-15 19:57:44

+0

我敢打赌,行*(my_int)= 1中有一个警告; – frag 2011-06-15 21:22:22

回答

2
int* my_int; 
*(my_int) = 1; 

这是未定义的行为。您没有初始化my_int,因此您正在取消引用无效指针。

相反,在你的MyView类中创建一个成员x,并更改为:

int* my_int = &x; 
+0

所以我应该这样做:int a = 1; int * my_int =&a; ? – Smash 2011-06-15 19:56:00

+0

@Smash:不完全。 'a'可能不是局部变量,因为它必须比线程寿命更长。 – ybungalobill 2011-06-15 19:56:59

+1

更好的是,只需跳过指针并在'reinterpret_cast (1)'中传递'AfxBeginThread'的第二个参数,并在'MyThread'内部将其作为'usescanner = reinterpret_cast (param)'转换回来。 – 2011-06-15 20:02:31

1

int* my_int; 

定义一个指向某个整数,未与实际整数的地址初始化,所以它指向内存中的一些随机地址

*(my_int) = 1; 

然后将值写入该随机地址。

正式地,这调用了可怕的未定义的行为。之后,所有投注都关闭。即使您的计算机会因此而爆炸,您的编译器也会符合标准。


然而,还有更多这样的:既然你传递一个指针的一些功能将被异步执行,您需要确保该对象的指针指的是“活着”,只要您其他线程将尝试访问它。基本上,这样做的唯一方法是使其成为全局,静态或动态分配。
但是,考虑到你的代码,我看不出你需要传递一个实际的指针。应该通过reinterpret_cast<LPVOID>(1)

0

上述两种正确的,但说这话的另一种方式:

*(my_int) = 1 

意味着:设定什么my_int点至1 - 但my_int尚未指向任何东西 - 热潮。

+0

指针总是指向某个东西。不过,这可能不是有效的。 – sbi 2011-06-15 20:00:18