Как выделить память с помощью этого оператора malloc?

У меня есть этот метод, который читает файл. Матрица, чтобы быть более конкретным, где первые два числа - это строки и столбцы. Однако, когда я пытаюсь выделить память с помощью malloc и строк и столбцов, происходит сбой приложения.

Я использую вот этот код:

#include stdio.h
#include stdlib.h
#include stdlib.h

float * readFile(char* nombre, int*renglones, int*columnas){
FILE *fp;
fp=fopen(nombre,"r");

fscanf(fp,"%d",&renglones);

printf("el numero de renglones es %d\n",renglones);

fscanf(fp,"%d",&columnas);

printf("number of rows %d\n",columnas);
float value;

fscanf(fp,"%f",&value);
printf("el numero de columnas es %f\n",value);
fscanf(fp,"%f",&value);
printf("el numero de columnas es %f\n",value);
printf("no llegue a malloc");
float * res = malloc(*renglones**columnas*sizeof(float)); //memory reservation and the line that breaks the program 
printf("after malloc");



fclose(fp);
return 0;

}

Я знаю, что включения находятся между ‹>

Окончательный код включает в себя: stdio.h и stdlib.h.

  float * readFile(char* nombre, int*renglones, int*columnas){
FILE *fp;
fp=fopen(nombre,"r");
fscanf(fp,"%d",renglones);
printf("el numero de renglones es %d\n",renglones);
fscanf(fp,"%d",columnas);
printf("el numero de columnas es %d\n",columnas);
float value;
float * res = (float*)malloc(*renglones**columnas*sizeof(float)); //Reserva de memoria
printf("llegue a malloc\n");
int i;
for(i=0;i<*renglones**columnas;i++){
        fscanf(fp, "%f",&value);
        res[i]=value;
        printf("dato %f\n",value);
}
printf("%d",i);
fclose(fp);
return res;

}

Спасибо!


person Mike930494    schedule 11.05.2013    source источник
comment
что такое rows и columns??   -  person yngccc    schedule 11.05.2013
comment
у меня есть изменение на columnas и renglones.   -  person Mike930494    schedule 11.05.2013
comment
Также таким образом float* res = (float*)malloc(rowscolumnssizeof(float)); но это не работает   -  person Mike930494    schedule 11.05.2013
comment
Использование (*renglones)*(*columnas)*sizeof… меняет ситуацию?   -  person Stefano Sanfilippo    schedule 11.05.2013
comment
@Stefano Sanfilippo: С чего бы это?   -  person Alexander Shukaev    schedule 11.05.2013
comment
Очевидный и единственный уместный вопрос: какое на самом деле число, которое вы передаете malloc? Первое, что вы должны сделать, это вычислить и вывести это число прямо перед вызовом malloc, чтобы увидеть, что вы передаете. Если вы пытаетесь сделать что-то вроде выделения отрицательного числа или выделения 50 ГБ, то сбой вполне ожидаем.   -  person Lee Daniel Crocker    schedule 11.05.2013
comment
@Haroogan Теоретически они одинаково верны, на практике лишний * может где-то проскользнуть и привести к сбою из-за глупых ошибок сегментации. Опубликовано как комментарий, так как это, очевидно, не ответ, в любом случае....   -  person Stefano Sanfilippo    schedule 11.05.2013
comment
Хороший компилятор должен был выдать много диагностических данных о вашем коде, и это должно было сказать вам, что у вас есть ошибки косвенности из-за неправильной интерпретации аргументов вашей функции. Всегда компилируйте с -Wall или эквивалентными флагами компилятора.   -  person Jens Gustedt    schedule 11.05.2013


Ответы (1)


Ваша проблема в том, что вы делаете:

...
fscanf(fp,"%d",&renglones);
...
fscanf(fp,"%d",&columnas);
...

В результате эти 2 числа (которые вы читаете из файла) становятся указателями на renglones и columnas, которые вы далее разыменовываете, чтобы вычислить размер для malloc. Например, если вы читаете числа 16 и 32, то renglones указывает на 0x00000010, а columnas указывает на 0x00000020. Однако эти ячейки памяти заведомо содержат случайный мусор (с точки зрения вашей задачи), т.е. они наверняка содержат сколь угодно огромные числа, которые при перемножении дают еще большее число, и malloc просто не может выделить такой объем памяти, что в итоге и приводит в аварии.

Вместо этого должно быть:

...
fscanf(fp,"%d",renglones);
...
fscanf(fp,"%d",columnas);
...

поскольку и renglones, и columnas уже являются указателями. Таким образом, вы действительно заполните две переменные int, на которые указывают renglones и columnas, и получите ожидаемое поведение.

person Alexander Shukaev    schedule 11.05.2013