#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
.