wcstok_s seems to be causing my application to crash
-
I am building a data logger that I want to use with an arduino as its input.
I have my application that works perfectly for the stage it is in for about a minute, then it crashes. when I run the program in debug mode, it eventually crashes and show the errors shown bellow. The bottom screenshot shows it failed on line 8321 of the dissembler file wcstok_s. does anyone know what wcstok_s is? and why is it causing this crash.
-
Hi and welcome to the forums
Its wide string functions
https://en.cppreference.com/w/c/string/wide/wcstokIn the call stack, further down, does it show where it came from in your code ?
-
Thanks for the reply.
The Stack does not show me on my code, but I have narrowed it down to the QSerialPort::WaitForReadyRead. This is the code for my Serial Receiver, it works really well for like 1 minute. this is a part of my SerialThread class that is running in its own thread. is there an alternative to the waitForReadyRead()? ```
//void SerialThread::readSerial()
{
while(serialBuffer.contains(';') == false)
{
serialData.append(arduino->readAll());
arduino->waitForReadyRead(100);
if(serialData.contains(';'))
{
break;
}
}
serialBuffer += QString::fromStdString(serialData.toStdString());
fullData = serialBuffer.split(",");
if(fullData.size()>0)
{
emit readSig(fullData);
qDebug() << fullData;
dataSizeInt = fullData.size()-1;
//qDebug() << dataSizeInt;
serialBuffer = "";
serialData.clear();
}}
-
Hi,
Why are you doing all these transformations ? Just cumulate the QByteArray you receive and only transform that to a QString when in makes sense. And for that part you still don't need to pass by the from/toStdString methods.
-
@SGaist I have my arduino spitting out a string, the problem is that when the readyread signal goes off I dont get the entire string from the arduino. Therefore I have this while loop that determines when the entire string is in. thats what the if statement is for. I know my code is not efficient, but I cant think of a better way to do it. also consider that there are 8 separate data points in the one string thats why I need to split the string into a QString list.
Do you know of a way to get my entire string everytime, without converting to a string and without the waitForReadyRead? Then can I pass the byte array through a signal to the rest of my application? is there a better way of getting my Serial data to my main thread without using global variables? Im a serious noob so input is much appreciated.
-
It's normal that you don't get the full data each time readyRead is emitted, there are several layers that can buffer data (outside of Qt's control).
My suggestion to use QByteArray still stands: just cumulate what you receive until you have a full frame of data and then process it.
-
@SGaist I am trying to figure this out, bellow is where I am at, this reads all of the data, but how do I search a Byte array for a certain alpha numeric character or a new line character?
void SerialThread::readSerial()
{
char str = ';';
while(arduino->bytesAvailable()
{
serialData.append(arduino->readAll());//Search byteArray and see if the final character is in }
}
-
Alright so after much trying I had troubles getting
QbyteArray.containts("\r\n") to return true for some reason, but I finally figured it out. bellow is for my self taught friends trying to do a serial connection. More experienced people please give me your thoughts as they are always appreciated, and thank you SGaist and mrjj for your help.This is the method in my own serialThread class so you will need to update the .h file then start it from the mainwindow thread etc:
void SerialThread::readSerial() { while(arduino->bytesAvailable()) { serialData.append(arduino->readAll()); //qDebug() << serialData; //serialBuffer += QString::fromStdString(serialData.toStdString()); //qDebug() << serialData.contains("\r\n"); if (serialData.contains("\r\n")) { //qDebug() << serialData; serialBuffer += QString::fromStdString(serialData.toStdString()); qDebug() << serialBuffer; serialData.clear(); serialBuffer = ""; break; } } }
-
@newSogn said in wcstok_s seems to be causing my application to crash:
Alright so after much trying I had troubles getting
QbyteArray.containts("\r\n") to return true for some reasonThat really smells as if
canReadLine()
andreadLine()
would exactly do what you want - and you would avoid keeping your own buffers.Some more notes:
serialData.clear();
is good,serialBuffer = "";
is not. Useclear()
in both cases.QString::fromStdString(serialData.toStdString());
No, never ever do this!QString::fromUtf8(serialData);
would be most often correct. If you are sure your serial data only contains ASCII, you could also useQString::fromLatin1(serialData);
which is a bit cheaper. Converting from and tostd::string
is just pointless.Regards
-
@newSogn said in wcstok_s seems to be causing my application to crash:
"\r\n"
Are you sure you don't get only "\n"?
-
And again: you should cumulate your data in a QByteArray as received from your serial device and only convert to QString when/if needed. If for some reason you get a null char, you'll lose some of the data because it's a string termination character.
-
@SGaist said in wcstok_s seems to be causing my application to crash:
If for some reason you get a null char, you'll lose some of the data because it's a string termination character.
Just for completeness, that also applies to
QByteArray
. -
@aha_1980 said in wcstok_s seems to be causing my application to crash:
ust for completeness, that also applies to QByteArray
No, a null byte isn't a problem in a byte array, it doesn't have any special meaning like in a string.
-
Just wondering whether this is still open?
I am running "similar" issue, can't conform for sure.
Here is my situation. everything works fine in qt 5.11.x, and recently, I upgraded my qt to 5.13.x and exactly same code starts segving.Here is a short description of my problem.
- a call from qml invokes a slot in C++
- then the C++ code will emit a signal
- qml side using Connections to monitor the signal and do some logic.
Code snippet blow:
- _station.orderManager.pending(
MyEnv.store,
"",
_currentUserBjid,
_currentUserBjid,
"DINEIN",
0,0,0,0
) - emit orderReceived(pid,
item.store(),
item.orderId(),
item.status(),
item.open(),
item.tax(),
item.priceNoTax(),
item.priceWidthTax(),
item.taxPrice(),
item.discountByPercentage(),
item.discountByCredit(),
item.gratitudeByPercentage(),
item.gratitudeByCredit(),
item.kind(),
item.createdOn(),
item.sequence(),
item.dailySequence(),
item.tableId(),
item.server(),
item.cashier(),
item.numOfAdult(),
item.numOfSenior(),
item.numOfKid(),
item.numOfFree(),
item.toJson()
); - Connections{
id: _realtime_con
target: _station.orderManager
onOrderReceived:{
console.log("received open order: " + order_id)
console.log("received open order: " + open)
console.log("received open order: " + created_on)