В этом коде есть несколько ошибок. Прежде всего, предупреждение относится к тому факту, что вы пытаетесь присвоить указатель на целое число (int *
) переменной (a
), которая является указателем на указатель на целое число (int **
), которое вы на самом деле хотите использовать в качестве массива массивов.
Итак, первая коррекция, в строке 8 это не
a=(int*)malloc(sizeof(int)*5);
но это
a=(int**)malloc(sizeof(int *)*5);
(это приведение в C не является строго необходимым, но, будучи программистом на C ++, я предпочитаю так держать)
Обратите внимание, что также изменилось выражение в sizeof
, поскольку вы хотите выделить не пространство для пяти целых чисел, а пространство для пяти указателей на целые числа.
Затем, в конце приложения, вы free
используете только пространство, выделенное первым malloc
, в то время как вы сделали другие пять выделений (по одному для каждой строки). Таким образом, вы можете выполнить освобождение в последнем цикле, сразу после отображения каждой строки.
for (i=0; i<5; i++)
{
for (j=0; j<3; j++)
{
printf("\nthe value enter enter the [%d][%d] location = ",i,j);
printf("%d",a[i][j]);
}
free(a[i]);
a[i]=NULL;
}
free(a);
a=NULL;
Помните: для каждого malloc
или calloc
вы должны иметь соответствующий free
, иначе вы теряете память.
Здесь, после каждого освобождения, я устанавливал соответствующий указатель на NULL
, чтобы отбросить те старые, теперь недействительные, указатели. Кто-то говорит, что такое поведение может маскировать двойные освобождения (поскольку free(NULL)
не вызывает ошибок), но ИМХО это лучше, чем альтернатива
Одна важная деталь: вы не проверяете возвращаемое значение malloc
, что довольно плохо. Крайне маловероятно, что в таких небольших программах распределение может завершиться неудачей, но, тем не менее, рекомендуется всегда проверять, равно ли возвращаемое значение malloc
NULL
, и, в этом случае, обрабатывать ситуацию изящно, обычно освобождая все ресурсы и закрывая приложение.
Кстати, system("clear");
безобразно. Вы должны использовать платформо-зависимый способ очистки экрана, даже лучше, если он включен в функцию; в Linux с обычными (X3.64) терминальными эмуляторами что-то вроде этого может быть в порядке:
void ClearScreen()
{
fputs("\x1B[2J\x1B[1;1H", stdout);
fflush(stdout);
}