Странная ошибка приведения LPVOID к указателю int - PullRequest
0 голосов
/ 15 июня 2011

Я получаю эту странную ошибку:

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.

Ответы [ 3 ]

2 голосов
/ 15 июня 2011
int* my_int;
*(my_int) = 1;

Это неопределенное поведение. Вы не инициализировали my_int, поэтому разыменовываете неверный указатель.

Вместо этого создайте члена x в своем классе MyView и измените на:

int* my_int = &x;
1 голос
/ 15 июня 2011

Это

int* my_int;

определяет указатель на некоторое целое число, не инициализируя его фактическим целочисленным адресом, поэтому он указывает на некоторый случайный адрес в памяти.
Это

*(my_int) = 1;

затем записывает значение в этот случайный адрес.

Официально, это вызывает ужасное Неопределенное поведение . После этого все ставки выключены. Даже если в результате этого ваш компьютер взорвется вам в лицо, ваш компилятор будет соответствовать стандартам.


Однако есть еще кое-что: поскольку вы передаете этот указатель какой-то функции, которая должна выполняться асинхронно, вам нужно убедиться, что объект, на который ссылается указатель, «жив» до тех пор, пока ваш другой поток будет пытаться чтобы получить к нему доступ. По сути, единственный способ сделать это - сделать его глобальным, статическим или динамически размещаемым.
Однако, учитывая ваш код, я не вижу причин, по которым вам все равно нужно передавать фактический указатель. Проход reinterpret_cast<LPVOID>(1) должен сделать.

0 голосов
/ 15 июня 2011

Вышеупомянутое и правильное, но иное выражение:

*(my_int) = 1

означает: установить, что my_int указывает на 1 - но my_int еще ни на что не указывает - boom.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...