Исключение, Dynami c выделение памяти в C - PullRequest
0 голосов
/ 10 марта 2020

Привет, я пытаюсь выполнить динамическое c выделение памяти большой матрицы в C, но я сталкиваюсь со следующей ошибкой:

Исключение, выданное в 0x00007FF63A248571 в cdempd.exe: 0xC0000005 : Место записи о нарушении прав доступа 0x0000000000000000. произошло

иногда это место записи о нарушении прав доступа 0xFFFFFFFFB412E2A0.

double ndivx, ndivy, ndivz, nt, r, box, dx, totnode;




int main()
{


    ndivx = 19.0;
    ndivy = 19.0;
    ndivz = 19.0;
    int totnode = ndivx * ndivy * ndivz;
    r = 0.005;  //diameter of sphere
    dx = 0.0025 / ndivx;
    double dx = r / ndivx; // distance between points



    int cols = 3;

    int** coords;
    coords = malloc(totnode * sizeof(int*));
    for (int i = 0; i < totnode; i++) {
        coords[i] = malloc(cols * sizeof(int));

    }


    //int* coord = (int*)malloc(totnode * cols * sizeof(int));


    //  int offset = i * cols + j;
    // now mat[offset] corresponds to m(i, j)
    //create a cube of equidistant points

    int numm = 0;
    for (int i = 1; i <= ndivx; i++)
    {
        for (int j = 1; j <= ndivy; j++)
        {
            for (int k = 1; k <= ndivz; k++)
            {

                coords[numm][0] = -1.0 / 2.0 * (r)+(dx / 2.0) + (i - 1.0) * dx;
                coords[numm][1] = -1.0 / 2.0 * (r)+(dx / 2.0) + (j - 1.0) * dx;
                coords[numm][2] = -1.0 / 2.0 * (r)+(dx / 2.0) + (k - 1.0) * dx;
                numm = numm + 1;


            }
        }
    }


}

pd.r является двойным 0,005, dx - двойным около 0,00026315, totnode - 6859.

I Я пробовал два метода: тот, который есть, и тот, который закомментирован с помощью //. Оба дают мне одну и ту же ошибку. Я использую Visual Studio 2019. Я не очень знаком с c и Visual Studio, так что простите, если вопрос глупый. Любая помощь будет оценена спасибо.

1 Ответ

1 голос
/ 10 марта 2020

Помимо некоторых других ошибок [после исправления], все значения coords установлены на ноль . Это потому, что coords является указателем на int и , а не (например) double, и в вашем уравнении используется -1.0 / ..., который всегда будет давать дробь.

Также, как Дэвид указал, вы индексируете с 1 [против 0] в петлях for. Это может вызвать нарушения прав доступа / segfaults.

Я изменил циклы for, чтобы начать с 0. И я соответствующим образом скорректировал уравнение (используя макрос).

Вы некоторые вещи, такие как индексные переменные или переменные размера, определялись как double вместо int (например) ndivx

Кроме того, я ввел typedef для значений координат.

Вот некоторый очищенный код, который может помочь вам продвинуться дальше:

#include <stdio.h>
#include <stdlib.h>

#if 0
double ndivx, ndivy, ndivz, nt, r, box, dx, totnode;
#endif

#if 0
typedef int coord_t;
#else
typedef double coord_t;
#endif

#define SETCOORD(_xidx,_var) \
    do { \
        coords[numm][_xidx] = -1.0 / 2.0 * r + (dx / 2.0) + (_var * dx); \
        printf("coords[%d][%d]=%g\n",numm,_xidx,(double) coords[numm][_xidx]); \
    } while (0)

int
main(void)
{
#if 1
    int ndivx;
    int ndivy;
    int ndivz;
    double r;
    double dx;
#endif

    ndivx = 19;
    ndivy = 19;
    ndivz = 19;
    int totnode = ndivx * ndivy * ndivz;

    r = 0.005;                          // diameter of sphere
    dx = 0.0025 / ndivx;
#if 0
    double dx = r / ndivx;              // distance between points
#else
    dx = r / ndivx;             // distance between points
#endif

    int cols = 3;

#if 0
    int **coords;
#else
    coord_t **coords;
#endif

    coords = malloc(totnode * sizeof(coord_t *));
    for (int i = 0; i < totnode; i++) {
        coords[i] = malloc(cols * sizeof(coord_t));
    }

    // int* coord = (int*)malloc(totnode * cols * sizeof(int));

    // int offset = i * cols + j;
    // now mat[offset] corresponds to m(i, j)
    // create a cube of equidistant points

    int numm = 0;

    for (int i = 0; i < ndivx; i++) {
        for (int j = 0; j < ndivy; j++) {
            for (int k = 0; k < ndivz; k++) {
                SETCOORD(0,i);
                SETCOORD(1,j);
                SETCOORD(2,k);
                numm = numm + 1;
            }
        }
    }

    return 0;
}
...