Unavailable synchronous data using QSharedData
-
wrote on 28 Nov 2011, 11:44 last edited by
Hello,
I wrote my first Implicit Sharing Class. Something goes wrong, I do not know why.Here is my implementation:
@
//mymap.h
#ifndef MYMAP_H
#define MYMAP_H#include <QSharedDataPointer>
#include <QVector>namespace kernel_interface {
class MyMapData;class MyMap
{
public:
MyMap();
MyMap(const MyMap &);
MyMap &operator=(const MyMap &);
~MyMap();
QVector<const float *> getValue(int type) const;
void appendValue(int type, QVector< const float *> value);
void appendValue(int type, const float * value);private:
QSharedDataPointer<MyMapData> _data;
};} /* end namspace kernel_interface */
#endif // MYMAP_H
@@
//mymap.cpp
namespace kernel_interface {MyMap::MyMap() : _data(new MyMapData)
{
}MyMap::MyMap(const MyMap &rhs) : _data(rhs._data)
{
}MyMap &MyMap::operator=(const MyMap &rhs)
{
if (this != &rhs)
_data.operator=(rhs._data);
return *this;
}MyMap::~MyMap() {}
void MyMap::appendValue(int type, QVector<const float * > value)
{
QVector<const float * > tmp = _data->_map.value(type);
tmp += value;
_data->_map.insert(type, tmp);
}void MyMap::appendValue(int type, const float * value)
{
QVector<const float * > tmp = _data->_map.value(type);
tmp.append(value);
_data->_map.insert(type, tmp);
}QVector<const float * > MyMap::getValue(int type) const
{
return _data->_map.value(type);
}}/* end namespace kernel_interface */
@
@
//mymapdata.h
#ifndef MYMAPDATA_H
#define MYMAPDATA_H#include <QSharedData>
#include <QMap>
#include <QVector>namespace kernel_interface {
class MyMapData : public QSharedData
{
public:
MyMapData() {}
~MyMapData() {
/* QMapIterator<int, QVector< const float *> > i(_map);
while(i.hasNext())
{
QVector< const float *> tmp = (i.next()).value();
QVectorIterator< const float > j(tmp);
while(j.hasNext())
{
delete j.next();
}
}/
qDebug() << "kaputt";
}
QMap<int, QVector< const float *> > _map;
};#endif // MYMAPDATA_H
} /* end namespace kernel_interface */
@
So now what happens:
@
//main.cpp
kernel_interface::MyMap func()
{
float *insert = new float[3];
insert[0] = 1.5;
insert[1] = 2.0;
insert[2] = 3.0;kernel_interface::MyMap ret; ret.appendValue(0, insert); return ret;
}
main() {
a = func(); // step 1
b.appendValue(0, a.getValue(0)); //* step 2*
a = func(); // step 3
b.appendValue(0, a.getValue(0)); // step 4
@The output after step 1
a kernel_interface::MyMap
_data QSharedDataPointer<kernel_interface::MyMapData>
QSharedData ref: 1 QSharedData
_map <1 items> QMap<int, QVector<float const*>>
[0] QMapNode<int, QVector<float const*>>
key 0 (0) int
value <1 items> QVector<float const*>
[0] 1.5 @0xb0c4c0 floatb kernel_interface::MyMap
_data QSharedDataPointer<kernel_interface::MyMapData>
QSharedData ref: 1 QSharedData
_map <0 items> QMap<int, QVector<float const*>>The output after step 2
a kernel_interface::MyMap
_data QSharedDataPointer<kernel_interface::MyMapData>
QSharedData ref: 1 QSharedData
_map <1 items> QMap<int, QVector<float const*>>
[0] QMapNode<int, QVector<float const*>>
key 0 (0) int
value <1 items> QVector<float const*>
[0] 1.5 @0xb0c4c0 floatb kernel_interface::MyMap
_data QSharedDataPointer<kernel_interface::MyMapData>
QSharedData ref: 1 QSharedData
_map <1 items> QMap<int_type, QVector<float const*>>
[0] QMapNode<int, QVector<float const*>>
key 0 (0) int
value <1 items> QVector<float const*>
[0] 1.5 @0xb0c4c0 floatThe output after step 3
a kernel_interface::MyMap
_data QSharedDataPointer<kernel_interface::MyMapData>
QSharedData ref: 1 QSharedData
_map <1 items> QMap<int, QVector<float const*>>
[0] QMapNode<int, QVector<float const*>>
key 0 (0) int
value <1 items> QVector<float const*>
[0] 1.5 @0xb0f650 floatb kernel_interface::MyMap
_data QSharedDataPointer<kernel_interface::MyMapData>
QSharedData ref: 1 QSharedData
_map <1 items> QMap<int, QVector<float const*>>
[0] QMapNode<int, QVector<float const*>>
key 0 (0) int
value <1 items> QVector<float const*>
[0] 0 @0xb0c4c0 floatThe output after step 4
a kernel_interface::MyMap
_data QSharedDataPointer<kernel_interface::MyMapData>
QSharedData ref: 1 QSharedData
_map <1 items> QMap<int, QVector<float const*>>
[0] QMapNode<int, QVector<float const*>>
key 0 (0) int
value <1 items> QVector<float const*>
[0] 1.5 @0xb0f650 floatb kernel_interface::MyMap
_data QSharedDataPointer<kernel_interface::MyMapData>
QSharedData ref: 1 QSharedData
_map <1 items> QMap<int, QVector<float const*>>
[0] QMapNode<int, QVector<float const*>>
key 0 (0) int
value <2 items> QVector<float const*>
[0] 0 @0xb0c4c0 float
[1] 1.5 @0xb0f650 floatSo why do the values in b get invalid when the =operator is applied on a? If I take bigger float areas the debugger says:unavailable synchronous data
Help is very much appreciated! kodiak
-
wrote on 28 Nov 2011, 20:29 last edited by
I am a step further. I figured out that the allocated memory by the float gets invalid for some reason. I do not know enough about it to say why. Maybe somebody can tell me, so I do understand more what I am doing.
What helped at least with =operator was deep copying the floats
@
MyMap &MyMap::operator=(const MyMap &rhs) {
if (this != &rhs) {
_data->_map.clear();
QMapIterator<int, QVector< const float *> > i(rhs._data->_map);
while(i.hasNext())
{
QVector< const float *> tmp = (i.next()).value();
QVector< const float *> tmp2;
QVectorIterator< const float *> j(tmp);
while(j.hasNext())
{
const float *p = j.next();
float *tmp3 = new float[3];
if(p != 0) {
mempcpy(tmp3,p, 3);
delete []p;
}
tmp2.append(tmp3);
}
_data->_map.insert(i.key(),tmp2);
}
}
}
@I do not know if I did it right, some feedback would be great!
1/2