Страницы

Поиск по вопросам

пятница, 20 марта 2020 г.

Как выделить память для большого двумерного массива в Си?

#c #массивы #память


Я работаю с большим двумерным массивом.
В случае, когда он размером 30 x 200, все считается. При больших объемах программа
вылетает... Мне посоветовали использовать memset(), но что-то не особо помогает...
Может быть у вас есть какие идеи?
#include 
#include 
#include 
#include 

double **B;

int main (int argc, char *argv[])
{ 
    int N, n_A;

    N = 32;
    n_A = 350; /* если сделать n_A = 200, то все работает */
    B = (double **)malloc(N * sizeof(double *));

    for(i = 0; i < N; i++)
    {
        B[i] = (double *)malloc(n_A * sizeof(double));
        memset(B[i], 0, n_A * sizeof(double));
    }

    free(B);

    return 0;
}
    


Ответы

Ответ 1



В целом код правильный, но нужно добавить проверку при выделении памяти: это необходимо, потому что памяти может просто не хватать, и в этом случае программа будет падать, потому что будет происходить запись в несуществующую память. То есть всякий раз, когда происходит вызов malloc, необходимо проверить, что возвращаемое значение не равно NULL. B = (double **)malloc(N * sizeof(double *)); /* Проверить, что память выделена */ if (B != NULL) { for(i = 0; i < N; i++) { B[i] = (double *)malloc(n_A * sizeof(double)); /* Проверить, что память выделена */ if (B[i] != NULL) { memset(B[i], 0, n_A * sizeof(double)); free(B[i]); } } free(B); } Кроме того, нужно не забывать освобождать память, выделяемую malloc внутри цикла, иначе будут утечки.

Ответ 2



Вот это все можно сделать одной строкой double * B; B = (double *) calloc (N * n_A, sizeof(double)); free (B); Вместо вызова кучи функций вы вызываете одну, которая сразу выделяет память под весь массив данных и обнуляет ее. Доступ к данным осуществляется по формуле double a; a = *(B + i * n_A + j); где i - номер строки, j - номер столбца

Ответ 3



При больших объемах программа вылетает... Локальный буфер(точнее размер стекового фрейма) не должен иметь размер больший одной страницы. Иначе произойдёт обращение за пределы сторожевой страницы стека, расширен он не будет и возникнет исключение.

Комментариев нет:

Отправить комментарий