Так много проблем в таком маленьком пространстве ... о дорогой!
Давайте сначала подумаем об интерфейсе ... как вызывающий код узнает, сколько значений возвращено? Предположительно, в конце массива указателей должен быть нулевой указатель. Кроме того, для каждого числа больше 1 мы знаем, что 1 и само число будут делителями, поэтому нам понадобится массив из по крайней мере 3 возвращаемых указателей. Если число не простое или единичное, в массив будет добавлено больше значений. Поэтому одна из вещей, которые нам нужно сделать, это следить за тем, сколько значений в массиве. Кроме того, код освобождения памяти должен будет пройти через возвращенный массив, освобождая каждую строку перед полным освобождением массива.
Итак, мы получаем некоторые идеи о том, что должен делать код. Как ваш код против этого?
char** calc_div(char nr[100])
{
int nri,i,ct=0;
char **a = (char**)malloc(sizeof(char*));
Это выделяет одну запись в возвращаемом массиве. Теперь мы знаем, что нам нужно как минимум в 3 раза больше места, и мы также должны вести учет того, сколько места было выделено.
nri = atoi(nr);
for(i=0;i<sizeof(char*);i++)
a[i] = (char*)malloc(sizeof(char));
Это выделяет 4 или 8 строк размером 1 байт каждая, присваивая их последовательным элементам массива размера 1, ранее выделенным. Это гарантированное переполнение буфера в массиве a
. Кроме того, поскольку строки достаточно велики для того, чтобы содержать нулевое значение в конце строки, вы не можете поместить в них ответы. Вероятно, вам следует выделить strlen(nr)+1
байтов, поскольку nr
- это одно из необходимых вам чисел. Удаленно не ясно, что числа ограничены 3 или 7 факторами (так как вам также необходимо разрешить завершающий нулевой указатель).
for(i=1;i<=nri;i++)
if(nri % i == 0)
{
sprintf(a[ct++],"%d",i);
}
Код внутри тела оператора if
должен быть готов к выделению памяти для нового фактора и для массива по мере необходимости.
return a;
}