Как освободить память временной строки? - PullRequest
1 голос
/ 27 ноября 2011

Я играю с моей собственной библиотекой строк, что, кстати, ужасно, но я делаю это ради опыта.

В любом случае, у меня есть некоторые функции, которые выделяют блок памяти для String*, и он работает нормально. Вся используемая память освобождается при вызове функции string_delete(string*). Но я придумал новый способ представления char* s как String* s, но я боюсь, что память, которую я зарезервировал для нее, не освобождается в будущем. Вот функция:

String* String_ToN(char* dest) {
  String* temp = calloc(1, sizeof (struct String));
  temp->length = strlen(dest);
  temp->buffer = (char*) malloc(temp->length + 1);
  strncpy(temp->buffer, dest, temp->length);
  return temp;
}

Мне не нравится использовать strdup, поскольку он не является стандартным c, поэтому я буду придерживаться malloc и strncpy.

Это работает, и то, для чего я его использую, выглядит примерно так:

String_GetLength(String*) принимает параметр String*, поэтому, если я добавлю строковый литерал при его вызове, я получу ошибку.

Так что вместо этого я иду String_GetLength(String_ToN("hello")) и он возвращает 5, как я ожидал.

Но опять же, в String_ToN я использую calloc и malloc, как бы мне освободить эту память и все еще иметь возможность использовать ToN?

Ответы [ 3 ]

2 голосов
/ 27 ноября 2011

В отличие от C ++, в C нет автоматического управления ресурсами (потому что нет деструкторов). Вы должны сделать что-то вроде:

String *hello = String_ToN("hello");
int len = String_GetLength(hello);
String_free(hello);

, где String_free выполняет всю необходимую очистку.

1 голос
/ 27 ноября 2011

Вам нужна функция для удаления или освобождения ваших String -s, возможно,

void String_delete(String *s) {
  if (!s) return;
  free (s->buffer);
  // you might want memset(s, 0, sizeof(*s)); to catch more bugs
  free (s);
}

. Возможно, вы захотите обнулить (как в прокомментированном коде) память до free -из этого.Это могло бы помочь поймать ошибки повисших указателей.Но вы можете использовать такие инструменты, как valgrind , чтобы поймать их.Кроме того, использование сборщика мусора Boehm чрезвычайно полезно: вы можете использовать GC_malloc вместо malloc (и т. Д.) И не беспокоиться о вызове free или GC_free.По опыту вы обнаружите, что высвобождение памяти становится основной проблемой в больших проектах программирования (и нет, идиома RAII не является серебряной пулей).

0 голосов
/ 27 ноября 2011

Как указал Оли Чарльзуорт, вы должны создать временный объект. Тем не менее, вы также можете добавить флаг

int dispose;

к вашей структуре String, а затем установите ее при переходе к какой-либо функции. Затем каждая функция, которая получает ваш String, должна проверить этот флаг и, если установлен, освободить структуру String. Код может выглядеть так:

Process_String(String_ToN("Hello", 1));

тогда

Process_String(String *str) {
    /* do smth with str */
    if(str->dispose)
        String_Delete(srt);
}

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

...