#c #multithreading
#c #многопоточность
Вопрос:
Я считываю данные с com-порта. Поскольку я не знаю, когда поступают данные, я непрерывно читаю в потоке.
Когда я прочитаю достаточно байтов, я сообщаю об этом основному потоку, отправляя сообщение с указателем на строку:
msg[i] = '';
completeMsg = new char[i];
strcpy(completeMsg, msg);
PostMessage(hDlg, BT_MSG, NULL, (LPARAM) completeMsg);
i = 0;
Ответ основного потока на это сообщение:
case BT_MSG:
{
char* msg = (char*) lParam;
ShowMsg(msg);
delete [] msg;
break;
}
Но похоже, что удаление в этом потоке запрещено, потому что я получаю эту ошибку, когда я перехожу к строке удаления:
Windows запустила точку останова в SPO.exe.
Это может быть связано с повреждением кучи, что указывает на ошибку в SPO.exe или любой из загруженных им DLL.
Это также может быть связано с тем, что пользователь нажимает F12 во время SPO.exe имеет фокус.
Окно вывода может содержать дополнительную диагностическую информацию.
Должен ли я использовать какую-либо глобальную переменную или отправить сообщение обратно, чтобы поток чтения обработал удаление? В нем нет atm с циклом обмена сообщениями, поэтому я бы предпочел не добавлять его только для этого.
Комментарии:
1. Разве это не должно быть new char [i 1]?
2. Так и должно быть -.- и сейчас это работает идеально. 🙂 Не знал, что это приведет к повреждению кучи. ^^’
Ответ №1:
Вы должны иметь возможность использовать new
в одном потоке и delete
в другом, при условии, что вы ссылаетесь на многопоточную библиотеку времени выполнения вашего компилятора.
Однако, похоже, что у вас действительно переполнен буфер. Вы завершаете нулевым значением msg
с помощью msg[i]=0
, но выделяете только i
байты — вам, вероятно, нужно new char[i 1]
.
Комментарии:
1. Мне интересно, действительно ли библиотеки MT переопределяют
new
иdelete
. Конечно, каждая операция должна быть атомарной, но виртуальная адресация остается неизменной…2. Спасибо, впервые использую threads, поэтому я действительно думал, что проблема была более сложной: P
Ответ №2:
Можно удалить память, выделенную в другом потоке, предполагая, что все правильно синхронизировано. В вашем случае поток вашего COM-порта не использует выделенный указатель после postMessage, поэтому удаление в основном потоке нормально.
Итак, мне интересно, получаете ли вы «обычное» повреждение кучи, которое не имеет ничего общего с потоковой обработкой. Проблема может быть в strcpy
зависимости от того, что именно i
означает. Помните, что strcpy
это приведет к записи завершающего нулевого символа. Вы, вероятно, хотите:
completeMsg = new char[i 1];