Reputation: 267
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
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
Reputation: 1
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
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