Ошибка памяти QMap

Я делаю один проект, в котором я определяю типы данных, как показано ниже.

typedef QVector<double> QFilterDataMap1D;

typedef QMap<double, QFilterDataMap1D> QFilterDataMap2D;

Затем есть один класс с именем mono_data, в котором я определяю эту переменную

QFilterMap2D valid_filters;



mono_data Scan_data // Class

Теперь я читаю одну переменную из файла .mat и пытаюсь сохранить ее в QMap "valid_filters" выше.

Код Qt: переключить вид

for(int i=0;i<1;i++)
    {
        for(int j=0;j<1;j++)
        {
            Scan_Data.valid_filters[i][j]=valid_filters[i][j];
            printf("\nValid_filters=%f",Scan_Data.valid_filters[i][j]);
        }
    }

Перенос выполняется успешно, но затем выдает ошибку времени выполнения

Windows активировала точку останова в SpectralDataCollector.exe.

Это может быть связано с повреждением кучи и указывает на ошибку в SpectralDataCollector.exe или любой из загруженных библиотек DLL.

В окне вывода может быть больше диагностической информации

Может кто поможет в решении этой проблемы. Мне это очень поможет.

Спасибо


person Saad Saadi    schedule 29.08.2013    source источник


Ответы (1)


Здесь разные проблемы:

<сильный>1. Использование двойного типа ключа для QMap

Использование QMap<double, Foo> — очень плохая идея. причина в том, что это контейнер, который позволяет вам получить доступ к Foo при наличии double. Например:

map[0.45] = foo1;
map[15.74] = foo2;

Это проблематично, потому что затем, чтобы получить данные, содержащиеся в map[key], вы должны проверить, является ли key равным, меньшим или большим, чем другие ключи в картах. В вашем случае ключ представляет собой double и проверяет, равны ли два double не является "безопасной" операцией.

<сильный>2. Использование int в качестве ключа, когда вы определили его как double

Здесь:

Scan_Data.valid_filters[i][j]=valid_filters[i][j];

i — это целое число, и вы сказали, что оно должно быть двойным.

<сильный>3. Ваш цикл проверяет только (i,j) = (0,0)

Вы знаете, что

for(int i=0;i<1;i++)
{
    for(int j=0;j<1;j++)
    {
        Scan_Data.valid_filters[i][j]=valid_filters[i][j];
        printf("\nValid_filters=%f",Scan_Data.valid_filters[i][j]);
    }
}

эквивалентно:

Scan_Data.valid_filters[0][0]=valid_filters[0][0];
printf("\nValid_filters=%f",Scan_Data.valid_filters[0][0]);

?

<сильный>4. Доступ к вектору с помощью operator[] небезопасен

Когда вы делаете:

Scan_Data.valid_filters[i][j]

Вы на самом деле делаете:

QFilterDataMap1D & v = Scan_Data.valid_filters[i]; // call QMap::operator[](double)
double             d = v[j];                       // call QVector::operator[](int)

Первый безопасен, и создайте запись, если она не существует. Второй не безопасен, j-й элемент в вашем векторе уже должен существовать, иначе произойдет сбой.

Решение

Кажется, вам действительно нужен двумерный массив double (т.е. матрица). Для этого используйте:

typedef QVector<double> QFilterDataMap1D;
typedef QVector<QFilterDataMap1D> QFilterDataMap2D;

Затем, когда вы хотите передать одно в другое, просто используйте:

Scan_Data.valid_filters = valid_filters;

Или, если вы хотите сделать это самостоятельно:

Scan_Data.valid_filters.clear();
for(int i=0;i<n;i++)
{
    Scan_Data.valid_filters << QFilterDataMap1D();
    for(int j=0;j<m;j++)
    {
        Scan_Data.valid_filters[i] << valid_filters[i][j];
        printf("\nValid_filters=%f",Scan_Data.valid_filters[i][j]);
    }
}

Если вам нужна трехмерная матрица, вы должны использовать:

typedef QVector<QFilterDataMap2D> QFilterDataMap3D;
person Boris Dalstein    schedule 29.08.2013
comment
Прежде всего большое спасибо за ответ. Для 3-й части, да, я знаю, что они эквивалентны... на самом деле размер моей матрицы 1*900... я просто проверял это с 1*1. для части решения я немного изменил его, и он отлично работает. Не могли бы вы дать мне несколько советов, как я могу написать код для 3D? typedef QVector‹double› QFilterDataMap1D; typedef QMap‹double, QFilterDataMap1D› QFilterDataMap2D; typedef QMap‹double, QFilterDataMap2D› QFilterDataMap3D; - person Saad Saadi; 29.08.2013
comment
@Saad Хорошо, рад, что это помогло :-) Да, то, что вы предлагаете, прекрасно. Однако, если вам нужно больше эффективности, вы можете использовать одномерный вектор размера sizeX * sizeY * sizeZ и получить доступ к элементам с помощью myEmulated3DArray[isizeYsizeZ + j*sizeZ + k]. Этот более поздний подход лучше по разным причинам, но я бы сказал, не беспокойтесь об этом сейчас, используйте самый простой подход :) - person Boris Dalstein; 29.08.2013
comment
@Саад. О нет, я только что понял, что вы снова использовали QMap. Нет! Забудьте о QMap, вас вводит в заблуждение название, это действительно не то, что вам нужно. :) Для 3D-матрицы используйте: QVector< QVector< QVector<double> > > - person Boris Dalstein; 29.08.2013
comment
Если я не ошибаюсь, то это правильный или неправильный синтаксис? typedef QVector‹double, QFilterDataMap1D› QFilterDataMap2D; - person Saad Saadi; 29.08.2013
comment
@Saad, мой плохой, я сделал ошибку в своем ответе из-за копирования и вставки. Этот синтаксис неверен, удалите double, посмотрите через 1 минуту мой обновленный ответ. - person Boris Dalstein; 29.08.2013
comment
Конечно, представление о том, что сравнение двойников как-то небезопасно, настолько же фальшиво, насколько это возможно. Двойник — это просто бинарное представление экспоненты, знака и мантиссы. Если у вас есть два из них, и они имеют одинаковое значение, они сравниваются равными. Если они не имеют одинакового значения, сравнение неравно. В этом нет никакой магии, поэтому, пожалуйста, давайте не будем распространять чушь. Теперь, если вы спрашиваете, всегда ли легко создать ту самую ценность, которую вы намереваетесь получить, то это может быть сложнее, но здесь это не имеет значения. Это действительно зависит от того, что вы пытаетесь сделать. - person Kuba hasn't forgotten Monica; 29.08.2013
comment
Уважаемый Борис. Не могли бы вы в этой новой теме, начатой ​​мной... это также касается qt, и я надеюсь, что вы поможете мне и в этом. stackoverflow.com/questions/18626426/.. - person Saad Saadi; 05.09.2013