How to delete linked list using free - c++

i've got these structures:
typedef struct tStimulus_tc
{
short Key;
struct tStimulus_tc *Next;
}Stimulus_tc;
struct Frame_tc
{
int ID; // Frame ID (0..MAX)
int Count; // Felt Count
short sSize; // Stimulus List Size
Stimulus_tc *sList; // Stimulus List
};
if i want to free a "struct Frame_tc" is this enough?
void freeFrame (Frame_tc *fTemp)
{
free(fTemp);
}
or i need to run throught it's stimulus and free 1 by 1?
what's the proper way to free a variable?

free() takes a previously allocated block and releases it for reuse. It doesn't know nor care about the contents of the buffer.
While you could write a compiler that recursively frees pointers, this isn't a good idea:
static Stimulus_tc stim;
Frame_tc *fTemp = malloc(sizeof *fTemp);
fTemp->sList = &stim;
fTemp->sSize = 1;
free(fTemp); // if this recursively freed pointers, we would free a static object
Only you know how your structure is constructed, therefore you shoud be the one destructing it. In your case that means walking the linked list and freeing each member.
In C++, it's advisable to use higher level mechanisms, like using a std::vector<Stimulus_tc> or std::list<Stimulus_tc>.
In cases where pointer use is inevitable (your case isn't one), consider using smart pointers. And if you absolutely must manage memory the old way, use type-safe new[]/delete[].

In C, if your Stimulus_tc list within the struct Frame_tc wrapper is not a traditional head/tail list (e.g. with the final ->Next = NULL), but with the number of nodes contained in list->sSize, you could do something similar to the following:
/* free all nodes in struct Frame_tc->Stimulus_tc list */
void free_list (struct Frame_tc *list)
{
Stimulus_tc *iter = list->sList; /* pointer to iterate list */
Stimulus_tc *victim = NULL; /* pointer to node to delete */
int n = list->sSize; /* number of nodes to delete */
if (iter == NULL) {
fprintf (stderr,"print_list() warning: empty list.\n");
return;
}
while (n--) { /* free n nodes */
victim = iter;
iter = iter->Next;
free (victim);
}
}
If you set the final Next pointer to NULL, you can eliminate int n = list->sSize; and simply iterate over the list with while (iter) { ...
If there were additional pointer elements within each node that were allocated, you would simply free those values before free (victim);
Look it over and let me know if you have any questions.

Related

does dynamically allocation structs in cpp require redefining elements?

Trying to implement the add function in dynamic list, recursively.
The code is self-explanatory:
struct list {
int value;
list* next = NULL; // is this valid?
};
list head;
void add(list* cur, int value) {
if (cur->next) {
add(cur->next, value);
return;
}
cur->next = (list*)(malloc(sizeof(list)));
cur->next->value = value;
cur->next->next = NULL; // withouth this line, the program errors out after two calls to the function add
}
int main() {
for (int i = 0; i < 50; i++)
add(&head, i);
}
After seeing the debugger, I realized that calling malloc wasn't initiating "next" with NULL as specified in the defininition of the list struct.
As noted in comments, malloc does not initialize anything. It simply grabs a chunk of memory big enough for a list struct. Now, that might mean that struct has next set to NULL, or it might not.
That is why you're having to explicitly initialize it to NULL as that prevents undefined behavior when accessing that member.
If you use new to handle dynamic memory allocation, then the next member is initialized to NULL.
cur->next = new list;
Including this use of malloc, your code is very C-ish, and there are numerous improvements C++ will allow you to make.

c++ Unable to initialize array of pointers to null c++

I am trying to create a trie, but when I initialize the pointers in the array to NULL it breaks the program. The program finishes but won't output anything. Why is it doing this I look at online examples and they are doing it.
class trie
{
private:
struct Node
{
char letter;
Node *children[26];
};
//the beginning of the trie
Node *root;
public:
/* Constructors with No Arguments */
trie(void);
/* Destructor */
~trie(void);
//Function to insert string into the trie.
void insert(string word);
//Function to help insert
void insertHelper(string word, Node * & trieNode);
//Funtion to print the contents of the trie.
void printTrie();
//Function to get the index if a char matches.
int getIndex(char letter);
};
trie::trie()
{
/* Initialize the root of the node */
root = NULL;
for(int i = 0; i < 26; i++){
root->children[i] = NULL;
}
}
trie::trie()
{
root = NULL;
for(int i = 0; i < 26; i++){
root->children[i] = NULL; // you are following the nullptr
}
}
In modern C++ you should use nullptr instead of NULL. No, in fact you should be using smart pointers like std::shared_ptr<> and std::unique_ptr<> or std::vector<>.
I suggest you read #2 of the Ten Commandments for C Programmers
:
2: Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.
Clearly the holy scriptures were mis-transcribed here, as the words should have been ``null pointer'', to minimize confusion between the concept of null pointers and the macro NULL (of which more anon). Otherwise, the meaning is plain. A null pointer points to regions filled with dragons, demons, core dumps, and numberless other foul creatures, all of which delight in frolicing in thy program if thou disturb their sleep. A null pointer doth not point to a 0 of any type, despite some blasphemous old code which impiously assumes this.
"Following the NULL pointer" here means to dereference it.

Proper Way to Cleanup in a Function with Multiple Return Points

I have a recursive search algorithm, and I want to clean up my pointers after each call. However, I return in so many locations, it seems sloppy to put a delete or free before every one.
Is there a better way? Does me freeing them all at return of the function mean I should just allocate them on the stack instead of in the heap?
Note this is a parallel search (not shown in code), but the caller will never return before its children. Does this have any additional pitfalls for using the stack?
Example Code (Don't worry about the algorithm here):
//create a new struct state (using new), initialize and return (C style)
new_state()
free_list(state* node)//free a list
double minimax(state* node, state* bestState) {
if (base_case) {
return;
}
state* gb = new_state(); //single node
state* children = new_state(); //head of list
generate_children(children); //fill list
state* current = children; //traverse node
//recurse on child
double result = -minimax(current, gb);
if (case1) {
free(gb);
free_list(children);
return;
}
if (case2) {
//do stuff
}
while(current != NULL){
result = -minimax(current, gb);
if (case1) {
free(gb);
free_list(children);
return;
}
if (case2) {
//do stuff
}
current = current->next;
}
free(gb);
gb = NULL;
//More stuff (with children but not gb)
free_list(children);
return;
}
Here is a small sample of RAII:
First we have a struct that simply stores your items.
struct FreeAll
{
state* gb;
state* children;
FreeAll(state* g, state* c) : gb(g), children(c) {}
~FreeAll() { free(gb); free(children); }
};
Note that on destruction, the free() is called on both items. How to use it?
double minimax(state* node, state* bestState)
{
if (base_case) {
return;
}
state* gb = new_state(); //single node
state* children = new_state(); //head of list
// Initialize our small RAII object with the above
// pointers
FreeAll fa(gb, children);
generate_children(children); //fill list
state* current = children; //traverse node
//recurse on child
double result = -minimax(current, gb);
if (case1) {
return;
}
if (case2) {
//do stuff
}
while(current != NULL){
result = -minimax(current, gb);
if (case1) {
return;
}
if (case2) {
//do stuff
}
current = current->next;
}
//More stuff (with children but not gb
return;
}
The local variable fa is a FreeAll type. When this local goes out of scope, the destructor of fa is called which calls free on both the pointers that were stored in the struct. Also note the lack of any code at the return points to free the memory. This will be done by fa when it goes out of scope.
Note this is a simple example, and has none of the sophistication as other methods mentioned, but it gives you the basic gist of the RAII paradigm.
However, I return in so many locations, it seems sloppy to put a delete or free before every one.
Yes it does.
Is there a better way?
Yes. Smart pointers are a better way. But if you do not want to drop what you are doing, and learn how to use smart pointers before you can continue, (it can be hard the first time,) keep reading further down.
Does me freeing them all at return of the function mean I should just allocate them on the stack instead of in the heap?
Yes, you could do that. It would also perform better. But it will not work if you are planning on allocating a lot of memory.
Note this is a parallel search (not shown in code), but the caller will never return before its children. Does this have any additional pitfalls for using the stack?
The pitfalls are the same. With parallel code, you have to be careful.
There are many ways to avoid this problem. Smart pointers and stack allocation have already been mentioned.
Another way is to have only one exit point. This can get clunky at times, because, for example, it would mean that you would have to set a flag within your loop right before breaking out of it so as to know whether it terminated successfully or due to an error.
Another way is to allocate your pointers in function A, call function B to do the actual work, (passing it the allocated pointers,) and then once function B returns to function A, free the pointers.
ScopeGuard does the job for you.
https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Scope_Guard
void your_function()
{
Scope_guard const final_action = []{
free(gb);
free_list(children);};
// your code here
};

How to delete dynamically allocated struct consisting dynamically allocated array member in C++?

I am doing my homework which requires me to implement a Trie Tree without using vector. I have a struc defined as following:
typedef struct{
char _name;
int32_t * _children;
int32_t _children_size;
int32_t _children_capacity;
int32_t * _location;
int32_t _location_size;
int32_t _location_capacity;
} TrieTreeNode;
To reduce the memory use, I store all the pointers of TrieTreeNode into a global variable TrieTreeNode ** nodes_array. Then the _children member of each TrieTreeNode is just an array whose elements are int32_t indices to nodes_array.
For example, say we have TrieTreeNode * parent. To access its first child, we use nodes_array[parent -> _children[0]].
My question is how to delete the whole Trie Tree? I have tried the following approach (tail is the number of pointers nodes_array has):
void delete_node(TrieTreeNode *node){
delete [] node -> _children;
delete [] node -> _location;
}
void delete_tree(){
for (int i = 0; i < tail; i++){
delete_node(nodes_array[i]);
}
delete [] nodes_array;
nodes_array = NULL;
}
However, when I used both -ps -l command and GDB to monitor the memory use of my program before and after deleting a tree, the memory only decreases a little bit. The RRS goes from 13744 to 13156, while it is only 1072 before I build the tree.
Any suggestions will be appreciated!
You are not deleting the nodes, only the pointers within each node.
Consider this:
void delete_tree(){
for (int i = 0; i < tail; i++){
delete_node(nodes_array[i]);
delete node_array[i]; // Delete the node itself.
}
delete [] nodes_array;
nodes_array = NULL;
}
After calling delete_node to free the two pointers in each node, you should then delete the node itself delete node_array[i] to free up the remaining memory for each node.
Personally though, I am a fan of defining constructors and destructors for structures so that I don't have to remember to initialize everywhere I create them or do the extra deletion everywhere I might dispose of one.

C++ - Memory Leak - Pointers to Struct

I have a struct defined as follows:
typedef struct Edge {
...
struct Edge *next; // linked list
} Edge;
I use it in many functions. For example, print receives a pointer to a struct (root). In the function, I need initialize a new pointer to root (and use it in a while loop to traverse a linked list). I don't understand how memory leaks work in C++.
If I do the following :
Edge *e = root;
And then use e in a while loop :
while (e != NULL) {
// do stuff
e = e->next;
}
Do I have to free the pointer e? Since it points to a a struct I want to keep, I don't delete it? Or maybe should I use it that way?
void print(Edge* root)
...
Edge *e = new Edge;
e = root;
...
/* Free e */
delete e;
It sounds like you're getting confused between what a pointer is and its relation to allocating/freeing memory. You can have any number of pointers pointing at a chunk of memory, but the memory should only be freed once.
Here, you're passing an Edge* into print to know where to start printing. The local Edge* you declare doesn't need to have heap memory allocated to it, since e is just going to be used to point to the different elements of the linked list, not tracking the lifetime of the linked list.
In your case you don't need new or delete, you are using a pointer to index a linked-list.
Edge *e = root;
This create a pointer to the node pointed by root, both e and root points to the same object.
while (e != NULL) {
// do stuff
e = e->next;
}
This is perfectly fine to iterate over a linked list.
By the way this is OK for educational purpose, in production code I would rather advise to use the STL and std::list.
When you no longer need an object that you've created with new, you must end it's life-cycle with delete.