Присвоение 2d динамической строки одномерному массиву

#c #memory-management

#c #управление памятью

Вопрос:

Я пытаюсь присвоить значения i-й строки 2d-массива одномерному массиву. Эти массивы создаются динамически. Мой код:

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

#define N 10
#define FRAC 10

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

    int i, j;
    double **A, *B;

    A=(double**)malloc(sizeof(double)*N);
    for (i=0; i<N; i  ){
        A[i]=(double*)malloc(sizeof(double)*N);
    }

    for (i=0; i<N; i  ){
        for(j=0; j<N; j  ){
            A[i][j]=i*j/FRAC;
        }
    }

    B=A[0];

    for(i=0; i<N; i  )
        printf("%fn",B[i]);

    system("PAUSE");

    return 0;
}
  

При печати B все значения отображаются как 0.0000. В чем здесь проблема?

Ответ №1:

Если вы посмотрите на свой цикл:

 for (i=0; i<N; i  ){
    for(j=0; j<N; j  ){
        A[i][j]=i*j/FRAC;
    }
}
  

Вы увидите, что каждый элемент в A[0] включает умножение на, i == 0 поэтому все ваши B значения будут равны нулю.

Если вы назначите B = A[1] и принудительно переведете вычисления в режим с плавающей запятой, определив FRAC значение 10.0 (или добавив явные приведения), вы увидите кое-что более интересное в вашем printf цикле.

И, пока я здесь, пожалуйста, не приводите возвращаемое значение из malloc , в этом нет необходимости, и это часто скрывает ошибки. Вы также не выделяете A должным образом, что вы должны делать A = malloc(sizeof(double *) * N) ; к счастью для вас, double почти всегда имеет размер, по крайней мере, такой же, как указатель.

Это модифицированная версия вашей программы:

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

#define N 10
#define FRAC 10.0   /* CHANGED */

int main(int argc, char *argv[]) {
    int i, j;
    double **A, *B;

    A = malloc(sizeof(double *) * N);
    for(i = 0; i < N; i  ) {
        A[i] = malloc(sizeof(double) * N);
    }

    for(i = 0; i < N; i  ) {
        for(j = 0; j < N; j  ) {
            /* This is floating point now that FRAC is 10.0 */
            A[i][j]= i * j / FRAC;
        }
    }

    B = A[1];   /* A[0] is all 0.0 so we'll look at A[1] instead. */
    for(i = 0; i < N; i  )
        printf("%fn", B[i]);

    return 0;
}
  

Создайте следующее (что более интересно и поучительно, чем набор нулей):

 0.000000
0.100000
0.200000
0.300000
0.400000
0.500000
0.600000
0.700000
0.800000
0.900000
  

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

1. я действительно смущен atm 🙂 я пытался разобраться в этом часами. спасибо, сэр!

2. Спасибо за ваши советы по выделению памяти. Я должен улучшить управление памятью.

Ответ №2:

Оба i*j и FRAC являются целыми числами, а в C деление двух целых чисел приводит к целому числу, отбрасывая любые десятичные дроби, которые у вас обычно были бы.

Измените FRAC , чтобы оно явно было значением с плавающей запятой, например, используя 10.0 вместо 10 .