Krzysztow
6th December 2011, 18:33
Hello All,
probably this is a simple question, however (maybe due to being tired) I cannot see any solution. The code below is extracted and simplified part of my application (these are some factory methods, basing on xml input). However now it magically(?) crashes on something else, than my original application. But still, maybe the reason is the same.
I put both parts in main.cpp file. Hovewer originally have separated declarations and definitions.
Two classes used are as follows:
#include <QBitArray>
#include <QDebug>
//! Base class, with one pure virtual method doActionThatCrashes()
class PropertyConverter {
public:
virtual ~PropertyConverter(){}
virtual void doActionThatCrashes() = 0;
};
//! Inherits PropertyConverter and implements funciton that really crashes.
class PropertyBitmaskConverter:
public PropertyConverter
{
public:
PropertyBitmaskConverter(QBitArray &mask):
_bitmaskFromInternal(mask) {}
const QBitArray &mask(){return _bitmaskFromInternal;}
virtual void doActionThatCrashes();
private:
const QBitArray &_bitmaskFromInternal;//!\warning Edit, thanks to d_stranz: That was an error in this code, since reference to stack variable was being copied. Remvoe ampresand.
};
void PropertyBitmaskConverter::doActionThatCrashes() {
QBitArray array = this->mask();
int size = array.size();
qDebug()<<"The number of bits is"<<size;
}
And the code itself is:
PropertyConverter *createPropertyConverter();
QBitArray bitArrayFromString(QString &array, bool *ok);
QBitArray bitArrayFromChar(const char *data, int size, bool *ok);
int main(int argc, char *argv[])
{
PropertyConverter *bitmaskConverter = createPropertyConverter();
if (0 != bitmaskConverter) {
//! \note Here it DOES crash
bitmaskConverter->doActionThatCrashes();
}
return 0;
}
PropertyConverter *createPropertyConverter()
{
bool ok;
QString mask = "b'11101'";
QBitArray bitMask;
if (!mask.isEmpty())
bitMask = bitArrayFromString(mask, &ok);
if (!ok || bitMask.isNull())
return 0;
PropertyConverter *bitmaskConverter = new PropertyBitmaskConverter(bitMask);
//! \note Here this doesn't crash
bitmaskConverter->doActionThatCrashes();
return bitmaskConverter;
}
QDebug operator<<(QDebug dbg, const QBitArray& z)
{
QString text;
for (int i = 0; i < z.size(); ++i)
text.prepend(z.testBit(i) ? "1": "0");
dbg << text;
return dbg;
}
QBitArray bitArrayFromString(QString &array, bool *ok)
{
return bitArrayFromChar(array.toLatin1().data(), array.size(), ok);
}
QBitArray bitArrayFromChar(const char *data, int size, bool *ok)
{
if (0 != ok)
*ok = true;
if ( ((strncmp(data, "B'", 2) == 0) || (strncmp(data, "b'", 2) == 0)) &&
data[size - 1] == '\'') {
const int significantDataSize = size - 3;
QBitArray result(significantDataSize, false);
const char *bitPtr = &data[2];
for (int i = significantDataSize - 1; i >= 0; --i) {
if (*bitPtr == '1')
result.setBit(i, true);
++bitPtr;
}
return result;
} else
if (0 != ok) *ok = false;
return QBitArray();
}
In the code attached the crash occurs on the streaming by QDebug, in the doActionThatCrashes(). When doActionThatCrashes() is called inside createPropertyConverter it works fine. When it's called one stack call higher (in the main() function), on the same object (same virtual call) it does nasty things.
In original application, the crash occurs on the array.size() call in PropertyConverter::doActionThatCrashes(). Please, if anyone could help me with this problem, I would be very glad. It stops me from further development and my fine grade :(
Best regards,
Krzysztof
Edit: Oh, I almost forgot. This could be important. I am using Qt 4.7.4 (64bit) on Linux (Ubuntu).
probably this is a simple question, however (maybe due to being tired) I cannot see any solution. The code below is extracted and simplified part of my application (these are some factory methods, basing on xml input). However now it magically(?) crashes on something else, than my original application. But still, maybe the reason is the same.
I put both parts in main.cpp file. Hovewer originally have separated declarations and definitions.
Two classes used are as follows:
#include <QBitArray>
#include <QDebug>
//! Base class, with one pure virtual method doActionThatCrashes()
class PropertyConverter {
public:
virtual ~PropertyConverter(){}
virtual void doActionThatCrashes() = 0;
};
//! Inherits PropertyConverter and implements funciton that really crashes.
class PropertyBitmaskConverter:
public PropertyConverter
{
public:
PropertyBitmaskConverter(QBitArray &mask):
_bitmaskFromInternal(mask) {}
const QBitArray &mask(){return _bitmaskFromInternal;}
virtual void doActionThatCrashes();
private:
const QBitArray &_bitmaskFromInternal;//!\warning Edit, thanks to d_stranz: That was an error in this code, since reference to stack variable was being copied. Remvoe ampresand.
};
void PropertyBitmaskConverter::doActionThatCrashes() {
QBitArray array = this->mask();
int size = array.size();
qDebug()<<"The number of bits is"<<size;
}
And the code itself is:
PropertyConverter *createPropertyConverter();
QBitArray bitArrayFromString(QString &array, bool *ok);
QBitArray bitArrayFromChar(const char *data, int size, bool *ok);
int main(int argc, char *argv[])
{
PropertyConverter *bitmaskConverter = createPropertyConverter();
if (0 != bitmaskConverter) {
//! \note Here it DOES crash
bitmaskConverter->doActionThatCrashes();
}
return 0;
}
PropertyConverter *createPropertyConverter()
{
bool ok;
QString mask = "b'11101'";
QBitArray bitMask;
if (!mask.isEmpty())
bitMask = bitArrayFromString(mask, &ok);
if (!ok || bitMask.isNull())
return 0;
PropertyConverter *bitmaskConverter = new PropertyBitmaskConverter(bitMask);
//! \note Here this doesn't crash
bitmaskConverter->doActionThatCrashes();
return bitmaskConverter;
}
QDebug operator<<(QDebug dbg, const QBitArray& z)
{
QString text;
for (int i = 0; i < z.size(); ++i)
text.prepend(z.testBit(i) ? "1": "0");
dbg << text;
return dbg;
}
QBitArray bitArrayFromString(QString &array, bool *ok)
{
return bitArrayFromChar(array.toLatin1().data(), array.size(), ok);
}
QBitArray bitArrayFromChar(const char *data, int size, bool *ok)
{
if (0 != ok)
*ok = true;
if ( ((strncmp(data, "B'", 2) == 0) || (strncmp(data, "b'", 2) == 0)) &&
data[size - 1] == '\'') {
const int significantDataSize = size - 3;
QBitArray result(significantDataSize, false);
const char *bitPtr = &data[2];
for (int i = significantDataSize - 1; i >= 0; --i) {
if (*bitPtr == '1')
result.setBit(i, true);
++bitPtr;
}
return result;
} else
if (0 != ok) *ok = false;
return QBitArray();
}
In the code attached the crash occurs on the streaming by QDebug, in the doActionThatCrashes(). When doActionThatCrashes() is called inside createPropertyConverter it works fine. When it's called one stack call higher (in the main() function), on the same object (same virtual call) it does nasty things.
In original application, the crash occurs on the array.size() call in PropertyConverter::doActionThatCrashes(). Please, if anyone could help me with this problem, I would be very glad. It stops me from further development and my fine grade :(
Best regards,
Krzysztof
Edit: Oh, I almost forgot. This could be important. I am using Qt 4.7.4 (64bit) on Linux (Ubuntu).