LINUX.ORG.RU

[c][valgrind] Invalid read of size 8

 ,


0

2

Пишу программу для контроллера. Plain C. Простейшая работа с матрицами.

float** createMatrix(unsigned short int nrows, unsigned short int ncolumns)
{
    float **matrix;
    unsigned short int i;

    matrix = malloc(nrows * sizeof(float *));
    if (matrix == 0)
        fprintf(stderr, "out of memory\n");
    for (i = 0; i < nrows; i++)
    {
        matrix[i] = malloc(ncolumns * sizeof(float));
        if (matrix[i] == 0)
            fprintf(stderr, "out of memory\n");
    }
    return matrix;
}

void destroyMatrix(float** matrix,unsigned short int rows)
{
    unsigned short int i = 0;
    for (i = 0; i < rows; i++)
        free(matrix[i]);
    free(matrix);
}

float** subMatrix(float** m1,float** m2, unsigned short int nrows, unsigned short int ncolumns)
{
    float **resultMatrix;
    unsigned short int i,j = 0;

    resultMatrix = createMatrix(nrows,ncolumns);
    for (i = 0; i < nrows; i++)
        for (j = 0; j < ncolumns; j++)
            resultMatrix[i][j] = m1[i][j]+(-1*m2[i][j]);

    return resultMatrix;
}

Код работает, никаких проблем. Однако, при прогонке valgrind'ом выдается:

«Invalid read of size 4» Что бы это могло значить?

Ваша работа с матрицами рассчитана на использование [i][j] в коде простейших алгоритмов? Это можно сделать проще - создав дополнительный массив указателей на начало каждой строки.

Иначе - зачем иерархически выделять память? простого С-массива (одного вызова malloc) достаточно.

Во всяком случае смешно выглядят кусочки типа if (matrix[i] == 0) fprintf(stderr, «out of memory\n»);

nikitos ★★★
()
Ответ на: комментарий от nikitos

Ваша работа с матрицами рассчитана на использование [j] в коде простейших алгоритмов? Это можно сделать проще - создав дополнительный массив указателей на начало каждой строки.

Иначе - зачем иерархически выделять память? простого С-массива (одного вызова malloc) достаточно.

Во всяком случае смешно выглядят кусочки типа if (matrix == 0) fprintf(stderr, «out of memory\n»);

Ну я что делаю? Массив указателей на строки и привязываю строчку к каждому элементу массива.

А проверка из-за того, что матрицы могут быть достаточно большими, вдруг память кончится :)

RaySlava
() автор топика
Ответ на: комментарий от RaySlava

вот вывод, например:

==7119== 2 errors in context 3 of 11:
==7119== Invalid read of size 8
==7119==    at 0x4012CF: destroyMatrix (matrix.c:42)
==7119==    by 0x402616: Compress (compressor.c:171)
==7119==    by 0x403BFB: archive (main.c:36)
==7119==    by 0x403F2F: parseCommandLine (main.c:89)
==7119==    by 0x404050: main (main.c:120)
==7119==  Address 0x586fc68 is 0 bytes after a block of size 40 alloc'd
==7119==    at 0x4C27BBD: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==7119==    by 0x401108: createMatrix (matrix.c:10)
==7119==    by 0x401735: subMatrix (matrix.c:120)
==7119==    by 0x40258A: Compress (compressor.c:165)
==7119==    by 0x403BFB: archive (main.c:36)
==7119==    by 0x403F2F: parseCommandLine (main.c:89)
==7119==    by 0x404050: main (main.c:120)

RaySlava
() автор топика
Ответ на: комментарий от RaySlava

Вы меня неправильно поняли. Я предлагал выделять одним блоком память под все элементы матрицы, а не так как вы - отдельно под каждую строку/столбец.

Или вашим алгоритмам инденферентна потеря одной строки/столбца в матрице, после которой они могут продолжить работу, лишь выругавшиcь в stderr?

nikitos ★★★
()
Ответ на: комментарий от nikitos

Или вашим алгоритмам инденферентна потеря одной строки/столбца в матрице, после которой они могут продолжить работу, лишь выругавшиcь в stderr?

Да. Именно так. Потеря нескольких строк в моем случае ничего не решит. Сейчас как раз работаю над правильной обработкой такой ситуации, чтобы, кроме выругаться, еще и сигналила.

RaySlava
() автор топика

Разобрался. Оказалось, что была попытка два раза освободить память.

Всем спасибо.

RaySlava
() автор топика

погугли blas. И если хочешь делать сам, то используй структуры

struct flt_matrix {
   size_t nrow;
   size_t ncol;
   float *block;
};
И одномерный массив.
flt_matrix m;
...
m->block[i*m->row + j];

anonymous
()
Ответ на: комментарий от anonymous

погугли blas. И если хочешь делать сам, то используй структуры

И одномерный массив.

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

Какие-то еще вменяемые плюсы у этого подхода есть?

RaySlava
() автор топика
Ответ на: комментарий от RaySlava

>А что мне это даст?

blas - это эталонная реализация простейшей линейной алгебры. По крайней мере взглянуть на него будет не лишним.

aedeph
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.