c++ Unable to initialize array of pointers to null c++ - 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.

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.

Data Structure in C++. insertion in the beginning of the node in linked list

I am learning data structures in C++. This is a simple program for insertion
using links and nodes. The insertion takes place at the beginning of the node.
I do not understand some parts of the code.
In the function display() the pointer np points to the inserted info and then takes the value of the previous info using the next node. The next pointer is pointing to the previous info using the insert_beginning() function.
Displaying is done using the while loop. How does the next pointer change its value during each loop?
PS: The program runs fine.
#include<iostream>
#include<process.h>
#include<cstdlib>
using namespace std;
struct node
{
int info;
node *next;
}*start,*newptr,*save,*ptr;
node *create_new_node(int);
void insert_beg(node*);
void display(node*);
/*----------------------------------------------------------------------------------------------------------------------------
The pointer 'start' points to the beginning of the list.
Function 'create_new_node()' takes one integer argument , allocates memory to create new node and returns
the pointer to the new node.(return type: node*)
Function 'insert_beg()' takes node* type pointer as an argument and inserts this node in the beginning of the list.
Function display takes node* type pointer as an argument and displays the list from this pointer till the end of the list
------------------------------------------------------------------------------------------------------------------------------
*/
int main()
{
start=NULL;
int inf;
char ch='y';
while(ch=='y'||ch=='Y')
{
system("cls");
cout<<"enter information for the new node ";
cin>>inf;
cout<<"\ncreating new node. Press enter to continue ";
system("pause");
newptr = create_new_node(inf);
if(newptr!=NULL)
{
cout<<"\nnew node created successfully. Press enter to
continue. ";
system("pause");
}
else
{
cout<<"\nCannot create new node. ABORTING!! ";
exit(1);
}
cout<<"\nnow inserting this node in the beginning of the list.
Press enter to continue ";
system("pause");
insert_beg(newptr);
cout<<"\nNow the list is \n";
display(start);
cout<<"\nPress 'Y' to enter more nodes, 'N' to exit\n";
cin>>ch;
}
return 0;
}
node *create_new_node(int n)
{
ptr=new node;
ptr->info=n;
ptr->next=NULL;
}
void insert_beg(node *np)
{
if(start==NULL)
start=np;
else
{
save=start;
start=np;
np->next=save;
}
}
void display(node *np)
{
while(np!=NULL)
{
cout<<np->info<<" ->";
np=np->next;
}
cout<<"!!!\n";
}
To cut the long story short - per my understanding, your basic question is:-
display is done using the while loop. how does the next pointer change
its value during each loop??
This happens precisely in this line:-
np=np->next;
You are basically advancing the pointer to the node structure to another node structure whose address is in next member of the first node structure. This is text book stuff and any basic algo book should cover this thoroughly
HTH!
Your question is somewhat unclear. Especially because you state that:
PS:the program runs fine.
which it for sure does not. There is a bug that simply means this program will not work.
The problem is that create_new_node is not returning the pointer value
node *create_new_node(int n)
{
ptr=new node;
ptr->info=n;
ptr->next=NULL;
return ptr; // This line is missing
}
Besides that it is a really bad idea to use global pointer variables!
Here
struct node
{
int info;
node *next;
}*start,*newptr,*save,*ptr;
you define the struct node but you also define 4 variables, i.e. 4 pointers to node. These variables will be global, i.e. available in all your code. Something that you should never do.
Instead make local variables as needed - for instance:
node *create_new_node(int n)
{
node *ptr; // Local variable instead of global
ptr=new node;
ptr->info=n;
ptr->next=NULL;
return ptr;
}
Then for the insert_beg change it so that it returns a new start pointer - like:
node* insert_beg(node* start, node *np)
{
np->next=start;
return np;
}
and use it in main like:
node* start = NULL;
...
...
start = insert_beg(start, newptr);
BTW - In modern C++ you would never use raw pointers and you would never write your own list. Use smart pointers instead of raw pointer. Use the standard containers instead of writing your own.

Trie c++ implementation segmentation fault

I'm implementing a simple trie data structure in c++ using struct and pointers. When I pass a string to add in trie, it gives segmentation fault in the addString() function.
struct node {
char ch;
node *link[26];
node() : link(){}
};
node head;
void addString(node *n, string s) {
if (!s.length()) return;
if (!n -> link[(int)s[0] - 97]) {
node m;
m.ch = s[0];
n -> link[(int)s[0] - 97] = &m;
}
addString(n -> link[(int)s[0] - 97], s.substr(1));
}
int main(){
addString(&head, "red");
return 0;
}
I tried debug statements and even printed and matched the address values of newly created node and the one passed recursively, they were same.
PS I'm using head node as epsilon state.
You are using addresses of objects allocated on stack. node m; is on stack. It will be deleted as soon as you leave an if block in which it is declared. And you assign it's address to a node n -> link[(int)s[0] - 97] = &m; which lives longer than that.
n -> link[(int)s[0] - 97] = &m;
You're storing the address of m while it is destroyed at the end of its scope.
You should redesign your project with a proper memory management.
There are two problems that could explain segmentation fault:
the first is that you add a pointer to a local object m into your array of links. As soon as you return from the function the pointer will be dangling and you'll have UB. Allocate m properly: node *m = new node; Better: use unique_ptr instead of raw pointers.
you assume that the string contains only lower case letters between 'a' and 'z'. If the string would contain anything else, you'll go out of bounds and might cause memory corruption and UB. You should have at least an assert()
Here a small fix to address both issues, based on your current structure and approach:
struct node {
...
node(char c=0) : link(), ch(c) {}
~node() { for (int i=0;i<26; i++) delete link[i]; }
};
...
void addString(node *n, string s) {
if (!s.length()) return;
size_t c = tolower(s[0]);
if (c<'a' || c>'z') return; // char not ok-> do like end of string
if (!n -> link[c-'a']) {
n -> link[c-'a'] = new node(c);
}
addString(n -> link[c-'a'], s.substr(1));
}
Note that when you use pointers in a struct, you have to be extra-careful about the rule of 3. It will not hurt here, though, as you do'nt copy nodes yet.
Online demo

How to delete linked list using free

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.

why does "a->content" give me a address instead of a value?

now i have been making games for a few years using the gm:s engine(tho i assure you i aint some newbie who uses drag and drop, as is all to often the case), and i have decided to start to learn to use c++ on its own, you know expand my knowledge and all that good stuff =D
while doing this, i have been attempting to make a list class as a practice project, you know, have a set of nodes linked together, then loop threw those nodes to get a value at a index, well here is my code, and i ask as the code has a single major issue that i struggle to understand
template<class type>
class ListNode
{
public:
type content;
ListNode<type>* next;
ListNode<type>* prev;
ListNode(type content) : content(content), next(NULL), prev(NULL) {}
protected:
private:
};
template<class type>
class List
{
public:
List() : SIZE(0), start(NULL), last(NULL) {}
unsigned int Add(type value)
{
if (this->SIZE == 0)
{
ListNode<type> a(value);
this->start = &a;
this->last = &a;
}
else
{
ListNode<type> a(value);
this->last->next = &a;
a.prev = this->last;
this->last = &a;
}
this->SIZE++;
return (this->SIZE - 1);
}
type Find(unsigned int pos)
{
ListNode<type>* a = this->start;
for(unsigned int i = 0; i<this->SIZE; i++)
{
if (i < pos)
{
a = a->next;
continue;
}
else
{
return (*a).content;
}
continue;
}
}
protected:
private:
unsigned int SIZE;
ListNode<type>* start;
ListNode<type>* last;
};
regardless, to me at least, this code looks fine, and it works in that i am able to create a new list without crashing, as well as being able to add elements to this list with it returning the proper index of those elements from within the list, however, beyond that the problem arises when getting the value of a element from the list itself, as when i ran the following test code, it didn't give me what it was built to give me
List<int> a;
unsigned int b = a.Add(313);
unsigned int c = a.Add(433);
print<unsigned int>(b);
print<int>(a.Find(b));
print<unsigned int>(c);
print<int>(a.Find(c));
now this code i expected to give me
0
313
1
433
as that's what is been told to do, however, it only half does this, giving me
0
2686684
1
2686584
now, this i am at a lost, i assume that the values provided are some kind of pointer address, but i simply don't understand what those are meant to be for, or what is causing the value to become that, or why
hence i ask the internet, wtf is causing these values to be given, as i am quite confused at this point
my apologies if that was a tad long and rambling, i tend to write such things often =D
thanks =D
You have lots of undefined behaviors in your code, when you store pointers to local variables and later dereference those pointers. Local variables are destructed once the scope they were declared in ends.
Example:
if (this->SIZE == 0)
{
ListNode<type> a(value);
this->start = &a;
this->last = &a;
}
Once the closing brace is reached the scope of the if body ends, and the variable a is destructed. The pointer to this variable is now a so called stray pointer and using it in any way will lead to undefined behavior.
The solution is to allocate the objects dynamically using new:
auto* a = new ListNode<type>(value);
Or if you don't have a C++11 capable compiler
ListNode<type>* a = new ListNode<type>(value);
First suggestion: use valgrind or a similar memory checker to execute this program. You will probably find there are many memory errors caused by dereferencing stack pointers that are out of scope.
Second suggestion: learn about the difference between objects on the stack and objects on the heap. (Hint: you want to use heap objects here.)
Third suggestion: learn about the concept of "ownership" of pointers. Usually you want to be very clear which pointer variable should be used to delete an object. The best way to do this is to use the std::unique_ptr smart pointer. For example, you could decide that each ListNode is owned by its predecessor:
std::unique_ptr<ListNode<type>> next;
ListNode<type>* prev;
and that the List container owns the head node of the list
std::unique_ptr<ListNode<type>> start;
ListNode<type>* last;
This way the compiler will do a lot of your work for you at compile-time, and you wont have to depend so much on using valgrind at runtime.