I allocate memory for the array. I read the data from the file, and I either crashes, or zeros or strange numbers appear. Confused with the release of memory ... (

#include <stdio.h> #include <stdlib.h> #include <math.h> double **A; int n_A, m_A; int i, j; void read_matrix(const char *filename) { FILE *file = fopen(filename, "r"); /* m_A - число строк, n_A - число столбцов */ fscanf(file, "%d %d", &m_A, &n_A); A = (double **)malloc(n_A * sizeof(double *)); if (A != NULL) { for (i = 0; i < m_A; i++) { A[i] = (double *)malloc(n_A * sizeof(double)); if (A[i] != NULL) { memset(A[i], 0, n_A * sizeof(double)); free(A[i]); } fscanf(file, "%lf", &A[i][j]); } } } int main(int argc, char *argv[]) { clrscr(); read_matrix("data 2.dat"); free(A); getch(); return 0; } 
  • @Alcheringa No need to ask new questions in the comments: this does not fit the format of the forum, because it confuses the topic. When you have a new question, you need to open a new topic. - Nicolas Chabanovsky

6 answers 6

  1. It should be: A = (double **) malloc ( m_A * sizeof (double *));
  2. Memory free (A [i]); doing too early, it is obvious that in this function it is not necessary to release at all.
  3. For fscanf (file, "% lf", & A [i] [j]); must be j-loop to read all values
  • about the cycle on j agree. Regarding the memory - I have an array of 30x400 - i.e. I do not have enough space when declaring double A [m_A] [n_A]; Then when to free up memory in the main function? - Alcheringa
  • @Alcheringa There may not be enough memory in the stack, of course. Release in main, run the loop on i to m_A and delete everything that allocated A [i], and then already the array A. - IAZ

You do free(A[i]) , and then try to write something in A[i][j] , an error. By the way, there is no cycle for j at all. But I would advise you to completely refuse from dynamic allocation in this task, and use memory on the stack:

 double A[m_A][n_A]; 

and then the same, but without malloc and free . But this is if your goal is not to learn how to allocate memory :)

     //Функция readfromfile (FILE * fp, double ** p, int sz1, int sz2) //Входящее значение: FILE * fp - файл // double ** p - двумерный массив // int sz1 - строки // int sz2 - столбцы //Функция построчно считывает файл в массив void readfromfile (FILE * fp, double ** p, int sz1, int sz2) { int i,j; for(i=0;i<sz1;i++) for(j=0;j<sz2;j++) //Естесвенным образом считываем данные из файла fscanf(fp,"%Lf",&p[i][j]); //в двумерный массив. } //Функция create(int sz1, int sz2) //Входящее значение: // int sz1 - строки // int sz2 - столбцы //Функция создает двумерный массив SZ1 x SZ2 //Исходящее значение: double ** - двумерный массив SZ1 x SZ2 double ** create(int sz1, int sz2) { double ** temp = (double **) malloc(sz1 * sizeof(double *)); //Здесь и далее - некомментируемые for (int i=0; i<sz1; i++) //действия считаются очевидными - и не temp[i] = (double *) malloc(sz2 * sizeof(double)); //нуждаются в комментировании. return temp; } //Функция erase(double ** p, int sz1) //Входящее значение: // double ** p - двумерный массив // int sz1 - строки //Функция очищает память от двумерного массива void erase(double ** p, int sz1) { for (int i=0; i<sz1; i++) free(p[i]); free(p); } 
    • Here's a pancake) I sent the alarm without reading to the end)) Although in essence the same thing as I wrote, only with comments. - Sergey
    • What is the alarm - not in the know, for the first time on the portal. Your post is not seen at the time of writing comments. Yes, and the comments are more likely from the aggregate of curiosity "and what will come out on the site of a non-existent avatar on this portal" and the fact that I have stored something on my computer from the first year of uni :) - Alexander Chikovany
    • Comment - add a comment) Add an answer a little more. I myself was confused at first. In the absence of an avatar, the gravatar is displayed. How to put an avatar instead of it was somewhere a topic. - Sergey
    • omgomgomg, Serega, you chtol?) 2645 - Alexander Chikovany
    • Well, yes - Sergey

    fscanf (file, "% d% d", & m_A, & n_A);

    Don't you need to add a line break to the end?

    fscanf (file, "% d% d \ n", & m_A, & n_A);

    For example, so ..

    • No difference. The separator is perceived as a space, and a line break ... - Alcheringa
    • By the way, everything is fine with the shift, everything is transferred correctly. The question remains: why do lines 22 and 32 print zeros? - Alcheringa
    • You would put your input and output files, for example, on pastebin.com And that’s true, you have to guess. - y0prst
    • Well, in general, something I did not download there now ... In short, it turned out that through Turbo C it turns out like I said. It is not fully recorded in the output file, the last numbers are zeros. But, if you compile through Visual Studio, then everything is as it should. Those. the compiler failed? .. Do not tell me a good compiler for C? - Alcheringa

    Never make a similar hodgepodge out of code. Do not forget about the prototypes of functions. Well, sort this code, how it works, I don’t remember well, I’ll have to write comments.

     double ** Load_Matrix(int * colls, int * rows, char filename[32]){ FILE * mf; int i,j; double tmp; double ** p; if(mf=fopen(filename, "r")){ fscanf(mf,"[%d;%d]",colls,rows); printf("colls: %d\nrows: %d\n",*colls,*rows); p=Create_Matrix((*colls),(*rows)); for(i=0;i<(*rows);i++){ for(j=0;j<(*colls);j++){ fscanf(mf,"%Lf ",&p[i][j]); } } fclose(mf); return p; } else printf("No such file!\n"); } double ** Create_Matrix(int colls, int rows){ double ** p; int i; p=(double **)malloc(sizeof(double*)*rows); for(i=0;i<rows;i++){ p[i]=(double *)malloc(sizeof(double)*colls); } return p; } double ** Erase_Matrix(int rows,double ** p){ int i; for(i=0;i<rows;i++){ free(p[i]); } free(p); return NULL; } 

      Here they have rightly said that there is no cycle for j, but by and large this is not the case, but the fact that you are building NOT a TWO-DIMENSIONAL ARRAY, but an array of pointers to arrays with double type elements! In your case, you cannot use & A [i] [j]. It is necessary to write something like:

       { double *pd = A[i]; fscanf (file,"%lf",&pd[j]); } 

      If you need to do exactly the array (all elements are sequentially in memory) then:

       { double **A = calloc(m_A*n_A,sizeof(double)); double *pd; int i, j; for (i = 0; i < m_A; i++) for (j = 0; j < n_A; j++) { // вычислим адрес нулевого элемента i-ой строки // n_A - количество элементов в строке, каждый размером sizeof(double) pd = (double *)&((char *)A + i*n_A*sizeof(double)); // прочтем j-ый элемент i-ой строки fscanf (file,"%lf",pd+j); // в такой записи С-compiler // умножит на sizeof(double) сам } } 

      Successes in (system) programming.

      • one
        The author builds exactly a two-dimensional array and the use of & A [i] [j] in the scanf is quite legitimate, since it is necessary to change this value. You suggest using a one-dimensional array. What is also acceptable, if we remember that all two-dimensional arrays in memory are arranged linearly. BUT THE MAIN THING - you make a whole series of mistakes. I will not even list them - too much. - IAZ
      • Beg not agree with you. The author allocates memory first for the double address vector , and then in the loop for the lines of his 'massmva'. This is not a double array. About & in the calculation of the address of the beginning of the line I completely agree, this is a mistake. It is necessary: ​​pd = (double *) ((char *) A + i n_A * sizeof (double)); - avp
      • one
        @avp The author allocates memory for an array of pointers to a double, then writes pointers to a double array into each element of this array. Gets a normal structure - a two-dimensional array. Take a closer look. - IAZ
      • one
        @avp As already said you have a lot of mistakes. For example, double ** A = calloc (...); What it is? calloc returns a pointer, not a double pointer! Learn a topic - working with pointers. - IAZ
      • one
        @avp You seriously don’t know the difference between a pointer and a double pointer, or is it just such a joke - did you get bored and decided to talk? - IAZ