【问题标题】:Weird error casting an LPVOID to an int pointer将 LPVOID 转换为 int 指针的奇怪错误
【发布时间】:2011-06-15 19:50:17
【问题描述】:

我收到这个奇怪的错误:

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。

【问题讨论】:

  • 这真的可以编译吗? MyView 是转到标签还是类名?
  • 这只是一个简化的例子,但我猜下面的其他人找到了我的问题的原因。
  • 我敢打赌 *(my_int) = 1; 行中有一个警告;

标签: c++ pointers casting


【解决方案1】:
int* my_int;
*(my_int) = 1;

这是未定义的行为。你没有初始化my_int,所以你解引用了一个无效的指针。

相反,在您的 MyView 类中创建一个成员 x,然后更改为:

int* my_int = &x;

【讨论】:

  • 所以我应该这样做:int a = 1; int* my_int = &a; ?
  • @Smash:不完全是。 a 可能不是局部变量,因为它的寿命必须比线程长。
  • 更好的是,只需跳过指针并将reinterpret_cast&lt;LPVOID&gt;(1) 作为AfxBeginThread 的第二个参数传入,然后在MyThread 内将其转换为usescanner = reinterpret_cast&lt;int&gt;(param)
【解决方案2】:

这个

int* my_int;

定义一个指向某个整数的指针,而不用实际整数的地址对其进行初始化,因此它指向内存中的某个随机地址
这个

*(my_int) = 1;

然后将一个值写入这个随机地址。

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


但是,还有更多:由于您将该指针传递给某个要异步执行的函数,因此您需要确保该指针所指的对象在您的其他线程尝试时是“活动的”访问它。基本上,做到这一点的唯一方法是使其成为全局、静态或动态分配的。
但是,鉴于您的代码,我认为您没有理由需要传递一个实际的指针。通过reinterpret_cast&lt;LPVOID&gt;(1) 应该可以。

【讨论】:

    【解决方案3】:

    以上都正确,但换一种说法:

    *(my_int) = 1
    

    意思是:将 my_int 指向的值设置为 1 - 但 my_int 还没有指向任何东西 - 繁荣。

    【讨论】:

    • 指针总是指向某物。不过,它可能不是有效的。
    【解决方案4】:

    你可以使用

    AfxBeginThread(..., reinterpret_cast<LPVOID>(static_cast<INT_PTR>(input)));
    

    在你的线程函数内部

    int my_int = static_cast<int>(reinterpret_cast<INT_PTR>(rawInput));
    

    这也适用于枚举而不是 int

    【讨论】:

      猜你喜欢
      • 2015-07-01
      • 2012-06-25
      • 2021-05-07
      • 2015-11-19
      • 2017-02-12
      • 2012-03-02
      • 2014-05-02
      • 2021-01-29
      • 1970-01-01
      相关资源
      最近更新 更多