Получить все делители для числа в C - PullRequest
0 голосов
/ 11 марта 2012

Я пытаюсь построить функцию, которая принимает 1 параметр: число как char [] и возвращает символ ** с делителями в виде строк.

Я предложил следующую функцию, которая работает только для некоторых чисел.

char** calc_div(char nr[100])
{
int nri,i,ct=0;
char **a = (char**)malloc(sizeof(char*));
nri = atoi(nr);

for(i=0;i<sizeof(char*);i++)
    a[i] = (char*)malloc(sizeof(char));

for(i=1;i<=nri;i++)
    if(nri % i == 0)
    {
        sprintf(a[ct++],"%d",i);
    }

return a;
}

Это работает для чисел типа 22, 33, 77, но не для 66 или 88 (оно просто где-то застревает). Кто-нибудь может мне помочь?

Ответы [ 2 ]

5 голосов
/ 11 марта 2012

Так много проблем в таком маленьком пространстве ... о дорогой!

Давайте сначала подумаем об интерфейсе ... как вызывающий код узнает, сколько значений возвращено? Предположительно, в конце массива указателей должен быть нулевой указатель. Кроме того, для каждого числа больше 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;
}
0 голосов
/ 11 марта 2012

После

char **a = (char**)malloc(sizeof(char*));

a есть место для 1 указателя на символ ...

for(i=0;i<sizeof(char*);i++)
    a[i] = (char*)malloc(sizeof(char));

, но вы пытаетесь записать более одного элемента (если sizeof(char*) не окажется 1) .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...