Улучшение реализации программы переключения дел - PullRequest
0 голосов
/ 19 марта 2019

Я могу сказать, что в этом случае будет утечка памяти, и я ищу улучшения / стандартный способ решения проблем такого рода.

(например, как опытный / профессиональный пользователь C мог бы реализовать это)

Это простая программа переключения регистра. Его цель - дать ему PizZa и вернуть вам pIZza.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char changeCase(char ch){

    if ( (int)ch < 65 || (int)ch > 122){
        return ch;
    }else if ((int)ch < 91){
        return (char)(ch + 32);
    }
    else{
    return (char)(ch - 32);
    }
}

char* toUpper(char* string){
    size_t size=strlen(string);
    char* temp = (char*) malloc(size);

    while (*string != '\0'){
        *temp = changeCase(*string);
        temp++;
        string++;
    }

    return (temp - size);
}


int main() {

    char* string = toUpper("PIZa");
    printf("%s",string);

    return 0;
}

Это приводит к утечке памяти, поскольку память из malloc не освобождается. Что было бы лучше? Выделить память вне функции и дать указатель на эту память функции toUpper? Другая идея?

Ответы [ 2 ]

4 голосов
/ 19 марта 2019

Стандартное правило де-факто заключается в том, что часть кода, которая выполняла динамическое размещение, также отвечает за его освобождение.Поэтому, если ваша функция была в каком-то файле "toupper.c", то в этом же файле C должна быть доступна какая-то функция очистки.

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

void toUpper (char* dst, const char* src)
{
  while (*src!= '\0')
  {
    *dst= ...
    ...
    dst++;
    src++;
  }
}

Здесь вызывающая сторона может выделять место для dst, как ему угодно, это не дело алгоритма.Например:

char str1[] = "hello world";
char* str2 = malloc(strlen(str1) + 1);
toUpper(str2, str1);
...
free(str2);

Просто убедитесь, что функция документирована так, чтобы вызывающий абонент знал, что ему нужно выделить место для dst - чтобы он был не меньше src.

*.1013 * Как примечание: char* temp = (char*) malloc(size); не так, вы не выделили место для нулевого терминатора.Также ваш алгоритм должен обязательно скопировать нулевой терминатор в буфер назначения.
1 голос
/ 19 марта 2019

Это приводит к утечке памяти, поскольку память из malloc не освобождается.

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

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

Пример:

int main() {
    char* string = toUpper("PIZa");
    printf("%s",string);

    string = toUpper("BRead"); // This causes a memory leak because after this
                               // line there is no longer any pointer to the
                               // memory allocated in the first call of toUpper

    string = NULL;             // Again this causes a memory leak because after this
                               // line there is no longer any pointer to the
                               // memory allocated in the second call of toUpper

    return 0;
}

Примечание: даже утечка памяти будет освобождена после завершения программы. Утечки памяти (в основном) являются проблемой в «долго» работающих программах.

Что было бы лучше? Выделение памяти вне функции ...

Ну, это вопрос вкуса.

В качестве примера: широко используемая (но нестандартная) функция strdup обрабатывает распределение внутри функции и требует от вызывающей стороны освободить память в дальнейшем.

Для функции, которая считывает неизвестное количество символов в качестве пользовательского ввода, также может быть полезно сделать mallocrealloc при необходимости) внутри функции.

Здесь действительно нет правильного или неправильного. Вы дизайнер, так что вы решаете. Все дело в «контракте функций», то есть в документации функции - как ее вызывать и что она будет делать.

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