I am trying to free some memory that I allocated in one functions in another function. An example of this would be:
MusicRec * createRecord(char * title, char * artist, double fileSize, int length, char theType)
{
MusicRec * newRecord;
MusicRec * next;
newRecord = malloc(sizeof(MusicRec));
newRecord->title = malloc(sizeof(char)*(strlen(title))+1);
strcpy(newRecord->title, title);
newRecord->artist = malloc(sizeof(char)*(strlen(artist))+1);
strcpy(newRecord->artist, artist);
newRecord->sizeInKB = fileSize;
newRecord->lengthInSeconds = length;
newRecord->type = theType;
newRecord->next = NULL;
next = NULL;
return(next);
}
I have malloced memory in that function, but now i am trying to free this malloced memory in a different function such as my main function. How would i do this?
Just use the corresponding deallocation function free() Remember you cannot use already deallocated memory at all.
Some points to consider:
Better change how you allocate memory, so you can more easily change the type:
Was: newRecord = malloc(sizeof(MusicRec));
Should be: newRecord = malloc(sizeof *newRecord);
Consider defining some helper functions for things you often do. Example (this function is often actually already defined):
Was: newRecord->title = malloc(sizeof(char)*(strlen(title))+1);strcpy(newRecord->title, title);
Should be: newRecord->title = strdup(title);
Never use sizeof(char): It looks illiterate, because you are literally asking: How many char's do I need to save one char?
For cases it's not defined:
char* strdup(const char* str) {
size_t len = strlen(str) + 1;
char* ret = malloc(len);
memcpy(ret, str, len);
return ret;
}
If you have passed that variable as reference from another function then you can free that variable from that function using free() function; otherwise you can not free that variable from another function if you have passed by value.
Related
so my first question would be. Does fgets overwrite other char* values?
Otherwise, I'm not really sure how I have messed up my mallocs. Below is the code where the value is changing. First line is where the variable is being created.
data[dataIndex++] = createVariable(varName, 1, value, -1, line, NULL);
The code where the variable is being created
Variable *createVariable(char *name, int type, int val, int len, int line, char *string)
{
Variable *var = malloc(sizeof(Variable));
var->name = name;
var->setting = type;
var->num = val;
var->length = len;
var->line = line;
var->string = string;
return var;
}
What data looks like and how it was created.
Variable **data;
data = malloc(4 * sizeof(Variable *));
Forgot to add this, but below is my fgets code
if (fgets(line, MAX_LINE_LENGTH, in) == NULL)
{
break;
}
The problem is this line in your createVariable function:
var->name = name;
What this does is copy the pointer given as the first argument to the name field in the var structure; it doesn't make a (separate) copy of the data that is pointed to! So, assuming you call createVariable many times with the same variable as the first argument, then every object created will have the same address in its name field, and any modifications you make to any of them (via fgets) will change all of them.
To get round this, you need to allocate new memory for the name field, each time you call the createVariable function, then copy the string data to it. The simplest way to do this is using the strdup function:
Variable *createVariable(char *name, int type, int val, int len, int line, char *string)
{
Variable *var = malloc(sizeof(Variable));
var->name = strdup(name);
//...
var->string = strdup(string);
//...
But note, you will now need to be sure to free that memory from each object when you (eventually) delete it. Something like this:
void deleteVariable(Variable** var)
{
free((*var)->name); // free the name memory
free((*var)->string); // free the string memory
free(*var); // free the actual structure
*var = NULL; // set the pointer to NULL - to prevent multiple frees
}
EDIT: Just re-read your question, and noticed that you are making the same mistake with the string field! The same fix needs to be applied to that!
I'm new to C and trying to figure out how to dispose of the structures, references to which are returned from a function.
For example, this is roughly what I want to do.
typedef struct test_t{
char *test_c;
} test_t;
int testFunc(test_t** output){
test_t* testStruct = malloc(sizeof(testStruct));
char* buf = malloc(sizeof(char) * 5);
strcpy(buf, "test");
testStruct->test_c = buf;
*output = testStruct;
return 0;
}
int main() {
test_t* test;
testFunc(&test);
printf("%s\n",test->test_c);
free(test);
return 0;
}
So in main I get the test struct. After printf (assume that there is some code after wards) I no longer need it and want to deallocate it. But how to do it properly? Should I just deallocate test_c explicitly first? But what if it wasn't allocated?
A structure can be deallocated just like any other pointer. You however have to ensure that all its allocated members are freed before doing so (failing to do so would most likely result in a memory leak of the members of your structure).
typedef struct test_t{
char *test_c;
} test_t;
int testFunc(test_t** output){
test_t* testStruct = malloc(sizeof(testStruct));
char* buf = malloc(sizeof(char) * 5);
strcpy(buf, "test");
testStruct->test_c = buf;
*output = testStruct;
return 0;
}
int main() {
test_t* test;
testFunc(&test);
printf("%s\n",test->test_c);
free(test->test_c);
free(test);
return 0;
}
In case your structure doesn't allocate all of its elements, you can set their pointer to NULL, which once passed to free (3) would be equivalent to doing nothing.
But how to do it properly? Should I just deallocate test_c explicitly first? But what if it wasn't allocated?
Basic rule of thumb: if you write a function that allocates a resource, write a complementary one that deallocates it. So when applied to your example:
void testFree(test_t* toFree) {
free(toFree->test_c);
free(toFree);
}
... and then ...
printf("%s\n",test->test_c);
testFree(test);
If testFree is implemented and exposed along with testFunc, the callers don't need to know your implementation details. The functions themselves, being part of the same library, will make sure the invariants are maintained properly. Should you ever switch allocation schemes, no calling code needs to change. You would just modify testFree to go along with the new testFunc and re-link.
First, you'll need to free the memory you,ve allocated for the char in the struct given that you have initialized it. Otherwise, you'll get an error so before any free instruction you should check whether the pointer that holds the memory position for test_p you're trying to free isn't NULL. Besides, the free instruction should take *test as a parameter instead of test.
You should have a procedure which allocates and initializes an instance of test_t. In C++ or other object-oriented languages this would be a constructor. In C you have to roll your own - something similar to the following:
test_t *create_test_t(char *init_test_c)
{
test_t *tt;
tt = malloc(sizeof(test_t));
if(init_test_c != NULL)
{
tt->test_c = malloc(strlen(init_test_c)+1);
strcpy(tt->test_c, init_test_c);
}
else
tt->test_c = NULL;
}
You'll also want a function to get rid of a test_t instance correctly. Something like:
void destroy_test_t(test_t *tt, bool static)
{
free(tt->test_c);
if(!static)
free(tt);
}
The static parameter is included to control whether tt should or should not be free'd. Obviously you don't want to attempt to free a pointer to a static instance of test_t, in which case you'd pass TRUE for static. For dynamically-allocated instances of test_t, e.g. those created using the create_test_t procedure, you'd pass FALSE for static.
You then use these functions every time you need to create or destroy a test_t.
Best of luck.
Should I just deallocate test_c explicitly first?
Yes, you have to free test_c first, because, if you free test, you will lose the reference to test_c.
But what if it wasn't allocated?
As you are returning int from testFunc, you can use it as a state of the allocation of your structure (although, returning a pointer would be a better idea IMHO):
int testFunc(test_t** output){
test_t* testStruct = malloc(sizeof(testStruct));
if (testStruct == NULL)
/* testStruct allocation failure. */
return -1;
char* buf = malloc(sizeof(char) * 5);
if (buf == NULL) {
/* buf allocation failure. */
free(testStruct);
return -1;
}
strcpy(buf, "test");
testStruct->test_c = buf;
*output = testStruct;
return 0;
}
After that, you check testFunc failure:
/* Check for allocation failure. */
if (testFunc(&test) == -1) {
fprintf(stderr, "Allocation error");
exit(EXIT_FAILURE);
}
/* Allocation succeeded. */
printf("%s\n",test->test_c);
free(test->test_c);
free(test)
So i have this struct which im using as a tree for a parser.
struct Expr{
struct Expr* a;
char* value;
struct Expr* b;
};
I initialize it with malloc like this.
Expr* initExp(){
Expr* ret;
ret = (Expr*)malloc(sizeof(Expr));
ret->a = (Expr*)malloc(sizeof(Expr));
ret->b = (Expr*)malloc(sizeof(Expr));
ret->value = (char*)malloc(sizeof(char));
ret->value = "18killstreak";
ret->a->value = "18killstreak";
ret->b->value = "18killstreak";
return ret;
}
I have written more here in the function than i needed to in the process of debugging so far and for printing the tree.
So I am trying to copy an Expr* a-> value into a Expr* value like this.
strcpy(temp2->value,ret->a->value);
While the values are "18killstreak" and "x" respectively.
But my program crashes at this line and I have tried many other tactics at this point.
The problem is that you're not managing memeory for your strings, so you can't just use strcpy. For example, when you have:
ret->value = (char*)malloc(sizeof(char));
ret->value = "18killstreak";
this allocats space for a 0-length string (just a NUL), and then throws it away (the memory leaks), overwriting the allocated pointer with a pointer to a static constant string "18Killstreak". When you later try to overwrite the static constant string (with strcpy) you get a crash.
So to do it correctly, you need to allocate and manage memory for the strings. The easiest way to do that is to have each struct Expr own the memory for the string and use strdup/free appropriately to alloc/copy/free that memory. So your init function becomes:
Expr* ret;
ret = (Expr*)malloc(sizeof(Expr));
ret->a = (Expr*)malloc(sizeof(Expr));
ret->b = (Expr*)malloc(sizeof(Expr));
ret->value = strdup("18killstreak");
ret->a->value = strdup("18killstreak");
ret->b->value = strdup("18killstreak");
Later when you want to replace the value of a struct, you do:
free(temp2->value);
temp2->value = strdup(ret->a->value);
and when you want to free an Expr, you need to also (first) free the value:
free(exp->value);
free(exp);
Now one isuue with this is that strdup is not a standard C function -- it's a POSIX function. So it is available on POSIX systems (such as Linux or OSX), but not on non-POSIX systems. So you may need to define it yourself:
char *strdup(const char *str) {
char *rv = malloc(strlen(str) + 1);
if (rv) strcpy(rv, str);
return rv;
}
I want to develop a library with ANSI C.
I have a string struct:
struct libme_string
{
char* buffer;
int length;
};
I want to write a function, libme_create_string(), that creates and initializes a string (like constructors in C++).
Which of these methods is better for designing libme_create_string()?
Method #1
Allocate memory for string object in libme_create_string() and return it:
struct libme_string* libme_create_string(int length)
{
// Check arguments...
// Allocate memory for object.
struct libme_string* str = malloc(sizeof(struct libme_string));
// Handle memory allocation errors...
str->buffer = malloc(length);
str->length = length;
// Handle memory allocation errors...
return str;
}
void libme_delete_string(struct libme_string* str)
{
// Check arguments...
free(str->buffer);
free(str);
}
Use
struct libme_string* str;
str = libme_create_string(1024);
// ...
libme_delete_string(str);
str = NULL;
Method #2
Do not allocate memory for string object in libme_create_string() function, accept it as an argument:
struct void libme_create_string(libme_string* str, int length)
{
// Check arguments...
// Just allocate memory for members.
str->buffer = malloc(length);
str->length = length;
// Handle memory allocation errors...
}
void libme_delete_string(struct libme_string* str)
{
// Check arguments...
free(str->buffer);
}
Use
struct libme_string str; // << different, not a pointer!
libme_create_string(&str, 1024);
// ...
libme_delete_string(&str);
Notes
string just a sample.
Method #2 is faster, isn't it?
Lastly, are there any good design guidelines for designing libraries written in C?
Personally, I would view the second version as less intuitive and more error prone.
If you're trying your hardest to encapsulate instantiation (which you should be doing anyway), then the first really is the only way to go — one step, done. The second version means that in order to have a fully initialized variable, you need to not only instantiate it, but you need to call a helper function on it immediately. That extra step is a bug waiting to happen.
Personally I prefer the first method. Agreed: it's a bit C++ like, but ...
thing_t *thing_new(...);
void thing_delete(thing_t *ptr);
I do think that all "size" or "count" members should be unsigned, preferably size_t.
Also: you last snippet tries to free() an automatic variable. That is a good reason not to use it.
EDIT:
There is (at least) a third way: return the entire object as a value. I don't particularly like the method, but it at least avoids the double allocation. It goes like this:
typedef struct {
StrLen length;
StrType type; /* type is not stored in the brainfile
**but recomputed on loading */
char *word;
} STRING;
STATIC STRING new_string(char *str, size_t len)
{
STRING this;
if (str) {
if (!len) len = strlen(str);
if (len) { this.word = malloc(len); memcpy(this.word, str, len); }
else { this.word = malloc(1); memset(this.word, 0, 1); }
this.length = len;
this.type = word_classify(this);
}
else {
this.word = NULL;
this.length = 0;
this.type = 0;
}
return this;
}
Typical usage goes like this:
if (*np == WORD_NIL) {
STRING this;
*np = dict->size++;
this = new_string(word.word, word.length);
dict->entry[*np].string = this;
dict->entry[*np].hash = hash_word(this);
}
(code inherited from megahal, reused in wakkerbot)
As I said, I don't like this method, but the struct assignment definitely has its advantages.
Why not factor the process into two functions, so you can use whichever you need:
struct libme_string * create_string();
void destroy_string(struct libme_string *);
struct libme_string * init_string(struct libme_string * str, unsigned int length);
struct limbe_string * deinit_string(struct libme_string * str);
Usage #1, all dynamic allocations:
struct libme_string * str = init_string(create_string(), 10);
destroy_string(deinit_string(str));
Usage #2, automatic outer struct:
struct libme_string str;
init_string(&str);
deinit_string(&str);
Make sure that the init functions return the pointer, so that you can compose the calls like I did.
If deinit() also sets the pointer to zero, then you could make destroy() call deinit() if the pointer is non-zero, though that breaks the symmetry a bit.
What is the right way to malloc memory ? And what is the difference between them ?
void parse_cookies(const char *cookie, cookie_bank **my_cookie, int *cookies_num)
{
*my_cookie = malloc(sizeof(cookie_bank) * 1);
*my_cookie = (cookie_bank *)malloc(sizeof(cookie_bank) * 1);
my_cookie = (cookie_bank **)malloc(sizeof(cookie_bank) * 1);
///
}
I'm trying to malloc array of cookie_bank structs function.
I'm assuming that you want the function to allocate memory for an array and passing the result via a pointer parameter. So, you want to write T * x = malloc(...), and assign the result to a pointer argument, *y = x:
cookie_bank * myarray;
parse_cookies(..., &myarray, ...);
/* now have myarray[0], myarray[1], ... */
So the correct invocation should be, all rolled into one line,
parse_cookies(..., cookie_bank ** y, ...)
{
*y = malloc(sizeof(cookie_bank) * NUMBER_OF_ELEMENTS);
}
Your second example is the most correct. You don't need the *1 obviously.
*my_cookie = (cookie_bank *)malloc(sizeof(cookie_bank) * 1);
Your first example is also correct, although some compilers/flags will cause a complaint about the implicit cast from void*:
*my_cookie = malloc(sizeof(cookie_bank) * 1);
It you want to allocate more than one entry you'd generally use calloc() because it zeros the memory too:
*my_cookie = (cookie_bank*)calloc(sizeof(cookie_bank), 1);
your third example is just wrong:
my_cookie = (cookie_bank **)malloc(sizeof(cookie_bank) * 1);
This will overwrite the local my_cookie pointer, and the memory will be lost on function return.
I just would like to recommend you to read some C textbook. It seems to me that you do not have clear understanding on how pointers work in C language.
Anyway, here is some example to allocate memory with malloc.
#include <stdlib.h>
void parse_cookies(const char *cookie, cookie_bank **my_cookie, int *cookies_num)
{
if (cookies_num == NULL || *cookies_num == 0) {
return;
}
if (my_cookie == NULL) {
my_cookie = (cookie_bank**)malloc(sizeof(cookie_bank*) * *cookies_num);
}
for (int i = 0; i < *cookies_num; i++) {
*my_cookie = (cookie_bank*)malloc(sizeof(cookie_bank));
my_cookie++;
}
}
Of course, this example does not cover any error handling. Basically, my_cookie is pointer to pointer which means my_cookie is just pointer to point memory location where it holds array of pointers. The first malloc allocate the memory using size of pointer and requested number of cookie structure. Then second malloc actually allocate memory for each structure.
The problem of this function is that it can easily cause memory leak unless using this very carefully.
Anyway, it is important to understand how C pointer works.