Calloc внутри функции - PullRequest
       27

Calloc внутри функции

1 голос
/ 09 февраля 2010

Глядя на этот вопрос, который только что был задан: Неудобства указателей на статические переменные будет ли что-то подобное делать плохой практикой?

char* strpart(char* string, int start, int count)
{
    char* strtemp; 
    int i = 0; int j = 0;
    int strL = strlen(string);

    if ( count == 0 )
    {
        count = strL;
    }

    strtemp = (char*) calloc((count + 1), sizeof(char));
    for ( i = start; i < (start+count); i++ )
    {
        strtemp[j] = string[i];
        j++;
    }
    return strtemp;
}

Извините, что написано быстро, но основной принцип - если НЕ использовать статический буфер внутри функции, это плохая практика - назначать память внутри функции? Я так полагаю, потому что это не будет освобождено, не так ли? Хотя я должен спросить.

Ответы [ 5 ]

5 голосов
/ 09 февраля 2010

Это не плохая практика, но она может легко вызвать утечки памяти (вызывающие должны помнить, чтобы освободить память).

Одна вещь, которую мне нравится делать, - это использовать соглашение об именах, чтобы указать, какие функции могут выделяться. Например, я бы назвал эту функцию:

char* strpart_alloc(char* string, int start, int count)
3 голосов
/ 09 февраля 2010

Практикуется всегда нормально динамически выделять память внутри функции. ПРЕДОСТАВЛЯЕТСЯ, что вы возвращаете указатель на эту память во внешний мир, чтобы что-то еще могло освободить ее или освободить ее самостоятельно внутри функции.

1 голос
/ 09 февраля 2010

Это не плохая практика. Тот факт, что функция возвращает malloc -эд (или calloc -эд) память, становится частью ее внешней спецификации. free становится обязанностью вызывающего абонента, когда в этом больше нет необходимости.

Хотя это не элегантно. Это не элегантно, так как 1) заставляет использовать динамическую память, когда вызывающая сторона может предпочесть ее избежать, и 2) принудительно использует определенный вид динамической памяти - malloc -оданную когда вызывающая сторона может предпочесть использовать собственный механизм выделения.

1 голос
/ 09 февраля 2010

Обычно это делают.Вы просто должны четко указать в своей документации «API», что вызывающая сторона должна освободить возвращенный указатель, когда закончите.

1 голос
/ 09 февраля 2010

Ну, это опасно. Я постараюсь избежать этого, когда это возможно.

Ваше предположение верно - память не будет освобождена автоматически.

Проблема в том, что возвращаемое значение здесь - это память, выделенная в куче, вызывающая ваша функция должна помнить об освобождении. Вы выделяете память, которая не будет (вами) освобождена. Это всегда плохая идея, чтобы накладывать ограничения на пользователя вашего API.

Иногда (редко) этого нельзя избежать, поэтому, если вы это сделаете, убедитесь, что документ очень четко задокументирован.

...