WedX - журнал о программировании и компьютерных науках

Проблемы с распределением памяти со структурой

  • Почему предоставленный код дает сбой в следующей строке?

    data *fillA = (data*)calloc(matrixa->nzmax, sizeof(data));
    

<суп>


#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <algorithm>
#include <time.h>
using namespace std;

struct csr
{
    int rows;
    int cols;
    int nzmax;
    int *rowPtr;
    int *colInd;
    double *values;
};

struct data
{
    int entry;
    int index;
};
bool descend(const data &a, const data &b)
{
    return a.entry > b.entry;
}

static bool ascend(const data &a, const data &b)
{
    return a.entry < b.entry;
}

void csrtranspose(struct csr *matrixa)
{

    int i, j, counter;
    double *tArray = NULL;
    data *fillA = (data*)calloc(matrixa->nzmax, sizeof(data));//fails here
    for (int i = 0; i < matrixa->nzmax; i++)
    {
        fillA[i].entry = matrixa->colInd[i];
        fillA[i].index = i;
    }
    sort(fillA, fillA + matrixa->nzmax, ascend);
    tArray = (double*)calloc(matrixa->nzmax, sizeof(double));
    for (int i = 0; i < matrixa->nzmax; i++)
    {
        tArray[i] = matrixa->values[i];
    }
    for (int i = 0; i < matrixa->nzmax; i++)
    {
        matrixa->colInd[i] = fillA[i].entry;
        matrixa->values[i] = tArray[fillA[i].index];
    }
    free(tArray);
    free(fillA);
}
int main()
{
    int i;
    struct data *total = 0;
    struct csr *s = 0;
    int nrows = 6, ncols = 5, counter = 0, nzmax = 10, rows = 3, cols = 5;
    double values[10] = {0.2135, 0.8648, 7, 0.3446, 0.1429, 6, 0.02311, 0.3599, 0.0866, 8 };
    int rowPtr[4] = { 0, 3, 6, 10 };
    int colInd[10] = { 0, 2, 4, 1, 2, 3, 0, 1, 2, 4 };
    s = (struct csr*) calloc(1, sizeof(struct csr));
    s->rows = rows;
    s->cols = cols;
    s->nzmax = nzmax;
    s->rowPtr = (int*)calloc(s->rows + 1, sizeof(int));
    s->colInd = (int*)calloc(s->nzmax, sizeof(int));
    s->values = (double*)calloc(s->nzmax, sizeof(int));
    for (i = 0; i<10; i++)
    {
        s->colInd[i] = colInd[i];
        s->values[i] = values[i];
        if (i <= s->rows)
        {
            s->rowPtr[i] = rowPtr[i];
        }
    }
    csrtranspose(s);
    getchar();
}

  • Нет необходимости использовать malloc в C++. Вы можете использовать new en.cppreference.com/w/cpp/memory/new/ оператор_новый 06.02.2015
  • Это больше похоже на C, чем на C++. 06.02.2015
  • Почему не data *fillA = new data[matrixa->nzmax];? 06.02.2015
  • @ Барри, я думаю, ты имеешь в виду, почему бы и нет std::vector<data> fillA(matrixa->nzmax); 06.02.2015
  • Есть есть причины, по которым вы можете захотеть использовать подпрограммы выделения C в C++, но в целом new и delete (а также new[] и delete[]) должны быть вашими инструментами выделения. Но также и в C++ подумайте об использовании std::vector или других коллекций сначала, прежде чем переходить к динамическому размещению. 06.02.2015
  • Я знаю, что могу использовать new, но причина, по которой это не удается, была бы полезна для понимания проблемы. 06.02.2015
  • Это 10, как показано в основной функции 06.02.2015
  • Вероятно, будет полезен MCVE. 06.02.2015

Ответы:


1

Строка (double*)calloc(s->nzmax, sizeof(int)); сама по себе является веской причиной для перехода к аллокации C++, где невозможно совершить эту ошибку, даже если вы скопируете и вставите.

Вы выделяете слишком мало памяти и записываете за пределы.

Поскольку все ваши размеры известны во время компиляции, вам вообще не нужно динамическое распределение.

06.02.2015
  • хехе, я опередил тебя на 2 секунды. 06.02.2015
  • Такая глупая глупая глупая ошибка. Это было частью большого кода 06.02.2015

  • 2

    Причина, по которой он падает, заключается в том, что память уже была повреждена ранее ошибочным кодом. Так что проблема не там, где он вылетает, проблема в коде, который выполнялся ранее.

    В частности, эта строка:

    s->values = (double*)calloc(s->nzmax, sizeof(int));
    

    Выделяет двойные значения, но использует sizeof(int), поэтому не выделяет достаточно памяти.

    РЕДАКТИРОВАТЬ

    Рекомендации:

    1. Как уже указывали другие, при работе с С++ используйте оператор new вместо выделения памяти в стиле C. Это избавит вас от МНОЖЕСТВ проблем.

    2. Если вы настаиваете на использовании выделения в стиле C, никогда не используйте p = (type*)malloc( sizeof(type) ), всегда используйте p = (type*)malloc( sizeof( *p ) ). Это, по крайней мере, сделает более очевидным, когда вы делаете очень распространенную ошибку выделения памяти для неправильного типа.

    06.02.2015
  • @VineetYadav Не волнуйтесь, это случается даже с лучшими. Обязательно прочитайте рекомендации, которые я добавил к своему ответу, чтобы уменьшить вероятность возникновения таких ошибок в будущем. 06.02.2015
  • Новые материалы

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    Для любых предложений по сайту: [email protected]