evolon696
evolon696

Reputation: 267

How to free memory of temporary string?

I am playing around with my custom string library which is terrible by the way, but I am doing it for experience.

Anyways, I have some functions that allocate a block of memory for String* to use and it works fine. All of the memory used is freed up when the string_delete(string*) function is called. But I came up with a new way of representing char*s as String*s but I am afraid the memory I reserve for it is not being freed down the road. Here is the function:

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;
}

I don't like using strdup being it is not standard c so I'll stick with malloc and strncpy.

This works and what I use it for is something like this:

String_GetLength(String*) takes in a String* parameter, so if I put a string literal in when calling it I would get an error.

So instead I go String_GetLength(String_ToN("hello")) and it returns 5 like I expected it to.

But again in String_ToN I use calloc and malloc, how would I free this memory and still be able to use ToN?

Upvotes: 1

Views: 1848

Answers (3)

Roman Byshko
Roman Byshko

Reputation: 9002

As pointed out by Oli Charlesworth, you must create temporaty object. However, you could also add a flag

int dispose;

to your String structure and then set it while passing to some function. Then every function that get's your String must check this flag and if set, free the String structure. The code might look like this:

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

then

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

I agree that this design is more error prone and not how the things get normally done. So consider it just as educational example, no more, no less.

Upvotes: 0

You need a function to delete or release your String-s, perhaps

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);
}

You might want to zero (as in the commented code) the memory before free-ing it. It might help catching dangling pointers bugs. But you could use tools like valgrind to catch them. Alternatively, using the Boehm's garbage collector is extremely useful: you can use GC_malloc instead of malloc (etc...) and don't bother calling free or GC_free. You'll find out by experience that releasing memory becomes a major issue in big programming projects (and no, RAII idiom is not a silver bullet).

Upvotes: 1

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272467

Unlike in C++, there is no automatic resource management in C (because there are no destructors). You would have to do something like:

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

where String_free does all the necessary cleanup.

Upvotes: 2

Related Questions