Unavailable synchronous data using QSharedData



  • 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 float

    b 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 float

    b 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 float

    The 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 float

    b 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 float

    The 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 float

    b 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 float

    So 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



  • 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!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.