Ошибка переполнения буфера в си

Дан бинарный файл вещественных чисел, содержащий элементы прямоугольной матрицы размера N на M, причём значения N и M хранятся в первых двух элементах файла. Создать новый бинарный файл того же формата, содержащий транспонированную матрицу


    #include <stdio.h>
    #include <stdlib.h>
    #include <malloc.h>
    #include <locale.h>
    
    int main() {
    
        setlocale(LC_ALL, "rus");
    
        FILE* fp;
        int N[2];
    
        if (fopen_s(&fp, "arr.bin", "rb") != 0) {
            printf("Ошибка открытия файла!");
            system("pause");
            return 0;
        }
    
        fread(N, sizeof(int), 2, fp);
    
        float** a = (float**)malloc(N[0] * sizeof(float*));
        for (int i = 0; i < N[0]; i++)
            a[i] = (float*)malloc(N[1] * sizeof(float)); 
    
        for (int i = 0; i < N[0]; i++)
            fread(a[i], sizeof(float), N[1], fp);
    
        if (fclose(fp) != 0)
            printf("Ошибка закрытия файла");
    
        if (fopen_s(&fp, "arr.bin", "wb") != 0) {
            printf("Ошибка открытия файла!");
            system("pause");
            return 0;
        }
    
        for (int j = 0; j < N[1]; j++)
            for (int i = 0; i < N[0]; i++)
                fwrite(&a[i][j], sizeof(float), 1, fp); 
    
    
        for (int i = 0; i < N[0]; i++) {
            free(a[i]);
        }
        free(a);
    
        if (fclose(fp) != 0) 
            printf("Ошибка закрытия файла");
    
        system("pause");
        return 0;

}

Ответы (1 шт):

Автор решения: Павел Ериков

Считывать динамическую матрицу из файла нужно построчно, т.к. для статической матрицы память под элементы выделяется прямолинейно, но не для динамической.

Вы пытаетесь поместить N[0] * N[1] элементов в a, то есть в первую строку матрицы, в случае со статической матрицей ошибки не было бы т.к. в памяти все элементы идут друг за другом и вторая группа из N[1] элементов поместилась бы уже на вторую строчку матрицы, но для динамической матрицы вы выделяете для каждой строчки память отдельно (для этого пишется цикл for)

По этому вместо:

fread(a, sizeof(int), N[0] * N[1], fp);

Нужно писать это:

for(int i = 0; i < N[0]; i++)
    fread(a[i], sizeof(float), N[1], fp);

P.s. надеюсь понятно объяснил

А так же у вас установлен не правильный режим открытия файла во втором случае.

В место rw (read, write) вам нужно wb (write, binary)

→ Ссылка