[Application crashes when I use std::reverse function to reverse a QString]
-
Hello again,
I hope you're doing well.
So After reading my csv file and displaying its values in a QTable which has 24 rows and 13 columns, I wanted to extract a part from the items that exist in the 9th column of every row, and then reverse them, and finally add them to a 10th column.
In fact I could only extract the parts I need and add each one to the 10 th column of every row, however when I add the reverse function , the application crashes when I run it.
Here is an explanation of what I want to do:
And here is what I tried to do :
for (int jx = 0; jx< colCount; ++jx) { setValueAt(rows, jx, values.at(jx)); //I'm adding other values std:: reverse(values.at(8).mid(90,8).begin(), values.at(8).mid(90,8).end()); setValueAt(rows,9,values.at(8).mid(90,8)); // I added another column which values are some extracted QString from an initial QString at the position 90
Also in the code, initially values is a QList, when I read the csv file, I store its data in a QList then I add them to QTable.
When I remove the reverse function everything works fine, The parts are extracted and added to the 10th column however when I use it to reverse the data extracted, the app crashes.
I ran it in debug mode, the problem seems to be in this line(160) in the qarraydata.h file
And in the output of the application, I get this message:
I don't really understand what's going on and what's the real problem.
Can anyone help me please ?
Any little help is really appreciated and thank you. -
@appdev said in [Application crashes when I use std::reverse function to reverse a QString]:
std:: reverse(values.at(8).mid(90,8).begin(), values.at(8).mid(90,8).end());
I don't know (believe) whether it's a good idea to
std::reverse()
anything in aQList
(actually aQString
) in place anyway. I think I'd rather take a copy, change it, and assign it back as necessary as a wholeQString
. Does that work without erroring?Also,
QString::mid()
returns a new (sub-)string. So at best you would be reversing a temporary copy of something copied out of aQString
, it won't alter the originalQString
. If anything you would need QStringRef QString::midRef(int position, int n = -1) const instead here. As I said, if that is even safe/allowed to be changed bystd::reverse()
. -
@J-Hilk said in [Application crashes when I use std::reverse function to reverse a QString]:
@JonB even worse, the call is to mid() twice, meaning begin() and end() point to completely different objects.
That is indeed a good observation :) Shouldn't
std::reverse()
complain that thebegin()
&end()
range do not refer into the same object? :)Then I suspect a (single!)
QString::midRef()
into theQString
could be passed asbegin
/end()
tostd::reverse()
and all should be well? -
@appdev said in [Application crashes when I use std::reverse function to reverse a QString]:
std:: reverse(values.at(8).mid(90,8).begin(), values.at(8).mid(90,8).end());
How to you expect this to work?
You are working with temporary created instances.
From QString::mid() documentation:Returns a string that contains n characters of this string, starting at the specified position index.
This will return a new QString instance.
This could work with
QString::midRef()
which returns a reference on current QString. -
First of all thank you for all your replies but there is something I still didn't really get.
The mid() which was called twice and begin()/end() range that don't refer to the same object.
Well, Yesterday I saw a post where someone wanted to reverse a QString.
The answer was as follows:
QString s = "variable"; std::reverse(s.begin(), s.end()); qDebug() << s; //output "elbairav"
So I thought that begin() points to the first character of the QString and end() to the last one.
I thought by doing:
values.at(8).mid(90,8).begin()
begin () would point to the first character of the extracted QString and end() to its last.
For example: let's say the 8th element of values which is a QList of QString is 123498f1258963.
mid(7,8) would return f1258963 and begin() would point to f and end() would point to 3.so to sum it all up,
values.at(8).mid(7,8)
would return f1258963 which is a QString
std:: reverse(values.at(8).mid(90,8).begin(), values.at(8).mid(90,8).end());
is the same as
std:: reverse(s.begin(), s.end());
where s is f1258963.
I didn't get what's wrong with mid() being called twice.
Also I included QStringRef but all I got was QStringRef file not found.
I also stored the values in the table and then tried to reverse them by accessing to their columns as follows:
reverse (mModel->item(rows,9)->text().begin(),mModel->item(rows,9)->text().end());
-
@appdev it's not pointing to the character, its pointing to the memory where the character is, of the temporary object, that mid() returns
setValueAt(rows, jx, values.at(jx)); //I'm adding other values auto subString = values.at(8).mid(90,8); std:: reverse(subString.begin(), subString.end()); setValueAt(subString);
-
@appdev said in [Application crashes when I use std::reverse function to reverse a QString]:
Also I included QStringRef but all I got was QStringRef file not found.
There was nothing to "include". [EDIT My bad. See @jsulm's post below about Qt6 which you are using.]
As said earlier, if you wish to reverse the characters in place in the middle of your string, you will need to use
QString::midRef()
. You currently passQString::mid()
tostd::reverse()
, so that would only reverse a copy of the mid section of the original string, not the mid section of the actual source string. -
@appdev You are mixing up several things which are (maybe similar) but not equivalent.
Yes you can use
std::reverse()
withQString
that's not the point here.The problem is
QString::mid()
returns a newQString
instance, that is what is wrong with your code.
Withstd:: reverse(values.at(8).mid(90,8).begin(), values.at(8).mid(90,8).end());
you are using 2 differentQString
instances.begin()
andend()
are not for the sameQString
instance.
It would be the same as doing:QString str1 = "My pretty string"; QString str2 = "My pretty string"; std:: reverse(str1.begin(), str2.end());
-
@appdev https://doc.qt.io/qt-5/qstring.html#midRef
What Qt version do you use? -
@appdev For Qt6 see https://doc-snapshots.qt.io/qt6-dev/qtcore-changes-qt6.html ("The QStringRef class" section).