My program is a list of cities, it's good but when I call to popFront(), I don't know why but it doesn't work, then I call any function and the program is over.
City* popFront(Nodo*& header, Nodo*& trailer) {
City* libras;
if (inicio) {
strcpy(libras->Name,inicio->dato.Name );
libras->Num = header->dato.Num;
Nodo* aux = header;
header= header->next;
header->previous= NULL;
delete aux;
if (!header) trailer = NULL;
}
return libras;
}
void read(Nodo*& head) {
Nodo* aux = head;
int pos = 1;
while (pos <= node_count) {
cout << "pos" << pos << endl;
cout << "Name> " << aux->dato.Name << endl;
cout << "NUm> " << aux->dato.Num << endl;
aux = aux->next;
pos++;
}
if (node_count == 0)cout << "Empty list" << endl;
}
Well, I'm not sure this is the only problem, but this right here is wrong:
City* libras;
You need to allocate it before you use it, like this:
City* libras = new City;
Otherwise, something like strcpy(libras->Name,inicio->dato.Name ); will fall and crash hard. That's because it's UB (Undefined Behavior) to access a pointer to memory that is unallocated.
Of course, you will need to delete it when you're done with it, but you seem to know and understand that already based on your other code:
delete libras; // Or wherever the returned pointer gets stored
Related
I have started learning c++ (coming from java background) and barely reached pointers and got stuck. When I debug this program it says, program received segmentation fault (SIGSEGV signal) at line
*previous = head;
in the following code.
#include <iostream>
using namespace std;
struct Node
{
int data;
Node *link;
};
int main()
{
cout << "Starting main program \n";
Node head;
head.data = 0;
head.link = NULL;
cout << "After declaring head and initializing values \n";
//Declaring a pointer variable which points to an entity of type struct.
Node *previous;
*previous=head;
cout << "After declaring previous pointer \n";
bool done = false;
int i = 1;
cout << "First while loop\n";
while(!done)
{
cout << i << ": Iteration";
Node temp;
temp.data=i;
temp.link=NULL;
if(i > 2)
{
done = true;
continue;
}
*previous->link=temp;
++i;
*previous = temp;
}
done = false;
cout << "Declaring temp pointer before printing \n";
Node *temp;
*temp = head;
cout << "Second while loop\n";
while (!done)
{
cout << i << ": Iteration";
if(temp == NULL)
{
done = true;
continue;
}
cout << temp->data << "->";
*temp = *temp->link;
}
cout << "NULL";
}
Why is the pointer initialization incorrect ?
First problem:
Node *previous;
*previous=head;
First line declares that previous will hold the address of a Node. It is not initialized, so whatever value happens to be on the stack will be picked up as the bit pattern it holds.
Unfortunately, the 2nd line then dereferences the pointer (which points to garbage) and attempts to copy head into random memory (hence your crash).
In this case you probably want previous to point to head, which is taking head's address and assigning it:
Node* previous = &head; // initialize at the point of declaration
However, you must also be very wary of pointers to variables declared on the stack, because the addresses will soon become invalid when the function returns or the scope exits.
(Usually data structures with pointers are using values allocated on the heap, so the objects outlive the function that declares them.)
Which brings us to the second problem:
while(!done)
{
cout << i << ": Iteration";
Node temp;
Already there's a problem. temp is declared inside the loop on the stack. Each loop iteration, the variable will automatically be destroyed. Therefore it cannot participate in your linked list without corrupting it.
You want your list nodes to be created with new, and when you update previous's next pointer, you want to assign an address TO it, not copy an object THROUGH it.
Something like this:
while(!done)
{
cout << i << ": Iteration";
Node * temp = new Node();
temp->data = i;
temp->link = nullptr; // better than NULL
if(i > 2)
{
break;
}
previous->link = temp;
++i;
previous = temp;
}
The head object should probably also be heap allocated. Of course, now you have to deal with cleaning up the memory by calling delete on all the nodes.
There were some bugs in the code but major ones were :-
you were not allocating memory for the new nodes that you were adding during runtime
you were creating instances of structure but instead you were required to create an pointer pointing to the structure ( instances will be created during runtime ( using new operator )
I have added the comments to the code explaining what exactly are the changes that I have done.
Here is the fix :-
#include <iostream>
using namespace std;
struct Node
{
int data;
Node *link;
};
int main()
{
cout << "Starting main program \n";
// Allocating memory for the new instance of Node and making "head" pointing to it
Node *head = new Node;
head->data = 0;
head->link = NULL;
cout << "After declaring head and initializing values \n";
//Declaring a pointer variable which points to an entity of type struct.
Node *previous;
// As head and previous both are pointers thus can be assigned as it is
previous = head;
cout << "After declaring previous pointer \n";
bool done = false;
int i = 1;
cout << "First while loop\n";
while(!done)
{
cout << i << ": Iteration";
// Allocating memory for the new instance of Node and making temp pointing to it
Node *temp = new Node;
// As temp is a pointer thus using member access ("- >") operator to access the members
temp->data=i;
temp->link=NULL;
if(i > 2)
{
done = true;
continue;
}
previous->link = temp;
++i;
previous = temp;
}
done = false;
cout << "Declaring temp pointer before printing \n";
Node *temp;
temp = head;
cout << "Second while loop\n";
while (!done)
{
cout << i << ": Iteration";
if(temp == NULL)
{
done = true;
continue;
}
cout << temp->data << "->";
temp = temp->link;
}
cout << "NULL";
}
I been programming a set of lists holing pointer to lists, and wanna create an convenient interface to brows them and save selected data from file to lists. The idea is that there is one "API list" with unique id, and whenever I find an unique id, I shall create a new API list. For now I'm stack on saving data to one "API list's" related lists.
The structure looks simply like this:
enum day { mon, tue, wed, thu, fri, sat, sun };
static const string enumValues[] = { "mon", "tue", "wed", "thu", "fri", "sat", "sun" };
struct _ListSub {
string h;
day d;
string gr;
string sub;
_ListSub *next = nullptr;
};
struct ListAPI {
string id;
ListAPI *next = nullptr;
_ListSub *head = nullptr;
};
And my function to read and save values from the file to the lists look like this:
ListAPI *createLists(string arg) {
ifstream f_in;
ListAPI *listGrip;
f_in.open(arg);
if (!f_in.is_open()) {
cout << "\"" << arg << "\": file does not exist!" << endl;
exit(EXIT_FAILURE);
}
listGrip = new ListAPI;
listGrip->head = new _ListSub;
while (true) {
// dummy data
string h;
string week = "";
string gr;
string id;
string sub;
if (!(f_in >> h >> week >> gr >> id >> sub)) {
break;
}
cout << "ID check: " << checkListID(id, listGrip) << endl;
listGrip->id = id;
listGrip->head->h = h;
listGrip->head->d = (day)enumerateDay(week);
listGrip->head->gr = gr;
listGrip->head->sub = sub;
listGrip->head ++;
listGrip->head = new _ListSub;
}
f_in.close();
return listGrip;
}
Any ways, the data is correct, it worked fine, so long didn't add this part (moving head pointer of _listSub and creating new instance of this object):
listGrip->head ++;
listGrip->head = new _ListSub;
All data that I'm getting out of this is id witch I save to listGrip (my list API), however all the data from the nested list list is gone.
Can someone tell me what I'm doing wrong here with pointers?
MAIN:
int main( int argc, char **argv ) {
/* Directly parse options in order to avoid accepting abbrevations. */
string ARGUMENT;
validate_arguments;
cout << "File path: " << ARGUMENT << endl;
ListAPI *listGrip;
listGrip = createLists( ARGUMENT );
//listGrip->head;
cout << "List has been created." << endl;
cout << "ID: " << listGrip->id << endl;
cout << "Subject: " << listGrip->head->sub << endl;
cout << "Time: " << listGrip->head->h << endl;
cout << "Day: " << getTextFromEnum((short)listGrip->head->d) << endl;
delete listGrip;
return EXIT_SUCCESS;
}
listGrip->head ++;
Makes no sense. head points to a single _ListSub. When you increment it, it will point to some random memory after the _ListSub you've allocated. This random memory is not yours and could lead to memory corruption or if you are lucky to a SegFault.
What you probably want is to insert at head:
auto new_head = new _ListSub;
new_head->next = listGrip->head;
listGrip->head = new_head;
Or even better use the Standard library. There's a std::list in there already, it's well tested and it works.
Linked-List is an abstract structure connecting loosely placed nodes. As nodes are not placed next to each other we can not preform pointer arithmetics to get to the next node. In stead we can create an insert function witch is going to redirect pointers for us.
Redirecting nodes:
Classical Linked-List contain the next pointer in it's structure, pointing to the next node of the same type. For convince we can add previous pointer and a size variable to keep track of list size.
void insertSub(string h, day d, string gr, string sub) {
auto newNode = new _ListSub;
//initialize
newNode->h = h;
newNode->d = d;
newNode->gr = gr;
newNode->sub = sub;
// point new node to the currently previous and next node
newNode->next = node->next;
newNode->prev = node;
// point currently next and previous node to the new node
node->next->prev = newNode;
node->next = newNode;
// increment size
++ node->size;
}
This works for my structure, but probably you wanna use constructor for object initialization.
I wrote a linked list and everything works fine but when I tried to use a particular function and print it I get an error I will be happy to help Why do I get an error and how to fix it.
The error occurs only when I call the ReverseNew-> print ();
function reverseList(in main.cpp):
List * reverseList(List &listToReverse){
List newList;
Node* currentPtr = listToReverse.getFirstNode();
while (currentPtr != 0){
newList.AddElement(currentPtr->getdata());
currentPtr = currentPtr->getNextPtr();
}
Node* currentNode = newList.getFirstNode();
int size = newList.size();
while (currentNode != 0){
currentNode->setId(size);
size--;
currentNode = currentNode->getNextPtr();
}
return &newList;
}
main:
int main(){
List l1;
l1.AddElement(1);
l1.AddElement(2);
l1.AddElement(3);
**l1.print(); >> Here he prints the list and works fine**
List* reverseNew = reverseList(l1);
**reverseNew->print(); >> here the program break**
system("pause");
return 0;
}
print function: (in List.cpp)
void List::print(){
Node* currentNode = firstPtr;
if (isEmpty())
std::cout << "List is empty" << std::endl;
else{
while (currentNode != 0){
std::cout << " < " << currentNode->data << " , " << currentNode->ID
<< " > " << std::endl;
currentNode = currentNode->nextPtr;
}}}
When the program comes out she takes me to this line: (in print function)
std::cout << " < " << currentNode->data << " , " << currentNode->ID
<< " > " << std::endl;
thabk's.
Inside reverseList(List &listToReverse) function body, you create a variable newList which goes out of scope and gets destroyed after the function ends its execution. When you try to reference that variable later in your code, that causes undefined behaviour, because you try to reference something that had already been deleted. Make newList a pointer instead to fix this (or, better, a smart pointer).
Once you remove part of the function it should be easier to see the issue:
List * reverseList(List &listToReverse){
List newList;
// ...
return &newList;
}
You return the address of a local variable. It's an Undefined Behaviour (UB).
To fix this you have two solution: return a copy of the object (beware of shallow copy issues), or use dynamic allocation in the function (check out the standard library smart pointer std::unique_ptr and std::shared_ptr/std::weak_ptr)
I need some help with my code. The function findNode lies within a header file, and is called in the main. As you can see, findNode calls itself until it finds the correct data value in each of the nodes. The type of tree implemented is a General Tree.
My problem is that the function does find the TreeNode it needs to find, but it returns it incorrectly. The data value of p in main is empty
TreeNode<Type>* findNode(Type &_data, TreeNode<Type>* _ptr)
{
if(_ptr->data == _data)
{
cout << "ptr->data: " << _ptr->showData() << endl;
return _ptr;
}
if(_ptr->children != NULL)
{
findNode(_data, _ptr->children->getHead());
}
if(_ptr->getNext() != NULL)
{
findNode(_data, _ptr->getNext());
}
}
In MAIN:
.
.
case 3:
{
string data;
cout << "****************" << endl;
cout << "***findNode()***" << endl;
cout << "Data to find: " << endl;
cin >> data;
TreeNode<string>* p = Tree->findNode(data, Tree->getRoot());
cout << "p->data = " << p->showData() << endl;
break;
}
add "return" in front of findNode(..) to fix the issue.
if(_ptr->children != NULL)
{
return findNode(_data, _ptr->children->getHead());
}
if(_ptr->getNext() != NULL)
{
return findNode(_data, _ptr->getNext());
}
unless the data matches in the first time, it is not returned. it is merely called and the result is let go.
In your original code, Say the data is matched in 4 th level of function call:
findNode1->findNode2->findNode3->findNode4
then this happens:
findNode4 returns ptr to findNode3, which does not return anything as it just called the function without expecting any value back.
At your level of skill it is very good to practice "uniform coding" :
retval = _ptr;
}
else if(_ptr->children != NULL)
{
retval = findNode(_data, _ptr->children->getHead());
}
else if(_ptr->getNext() != NULL)
{
retval = findNode(_data, _ptr->getNext());
}
return retval; // return from single point.
it is merely a style not technically better, but imho gradual learning is better.
I'm writing a code to index the skills available to a user in a game, constructed as a linked list. I've throughly tested the function that populates the list and it seems to be working correctly (so the head pointer for the list shouldn't be null). When I attempt to traverse the list to set values in the skill, before any of the code which writes to memory within the list gets to execute the program is crashing when I initialise the temp pointer within the search function of the list to the head pointer.
What makes this additionally weird to me is that it worked fine (and I had tested this fairly thuroughly) until I added in a list to store a list of available items, and may just be missing an odd interaction between the two when I populate them.
The specific error is that the pointer is supposedly accessing memory index 0x000000c to write to, but I don't see how the code at that point is dealing with a null pointer at all (since after 10 runs of the program the OS shouldn't be allocating that block of memory to the temp pointer every time and nothing else should be null.
I'm probably just ramblind at this point so here's the code:
The function that causes the error according to the debugger:
void Mechanics::setSkillValue(int index, int value)
{
Skill *temp = FirstSkill; // << The error is happening on this line //
while((temp != NULL)&&(temp->index != index))
{
temp = temp->next;
}
if (temp == NULL)
{
cout << "%";
}
else temp->setValue(value);
// cout << temp->returnValue(); //This was a test check, not needed for anything
}
The Function that's supposed to populate the skill and item lists.
void Mechanics::Populate()
{
ifstream skillstream("Skills.txt");
if(skillstream.is_open())
{
while(skillstream.good())
{
Skill *newskill;
int indexval;
string skillindex;
string skillname;
string skilldescription;
cout << "TP4" << endl; //TEST POINT
getline(skillstream, skillindex);
cout << skillindex;
getline(skillstream, skillname);
cout << skillname;
getline(skillstream, skilldescription);
cout << skilldescription; cout << endl;
indexval = atoi(skillindex.c_str());
newskill = new Skill(skillname, skilldescription,indexval);
//cout << "TP5" << endl; //TEST POINT
if(newskill == NULL) cout << "NULL!!!";
addSkill(newskill);
}
}
ifstream itemstream("Items.txt");
if(itemstream.is_open())
{
while(itemstream.good())
{
Item *newitem;
int indexval;
string skillindex;
string skillname;
string skilldescription;
string abilitydescription;
string valueSTR;
string typeSTR;
int value;
int type;
int numeric[5];
// cout << "TP4" << endl; //TEST POINT
getline(itemstream, skillindex);
// cout << skillindex;
getline(itemstream, skillname);
// cout << skillname;
getline(itemstream, skilldescription);
// cout << skilldescription;
getline(itemstream, abilitydescription);
getline(itemstream, valueSTR);
value = atoi(valueSTR.c_str());
getline(itemstream,typeSTR);
type = atoi(typeSTR.c_str());
for (int i=0; i < 5; i++)
{
string numericSTR;
getline(itemstream,numericSTR);
numeric[i]=atoi(numericSTR.c_str());
}
indexval = atoi(skillindex.c_str());
newitem = new Item(indexval, skilldescription, skillname, abilitydescription, value, type, numeric);
//cout << "TP5" << endl; //TEST POINT
// if(newskill == NULL) cout << "NULL!!!";
addItem(newitem);
}
}
The function that's supposed to actually add a skill to the skill list:
void Mechanics::addSkill(Skill *nskill)
{
Skill *temp = FirstSkill;
if(FirstSkill == NULL)
{
FirstSkill = nskill;
//cout << "TP1" << endl; //TEST POINT
//FirstSkill->printname();
}
else
{
while((temp->next != NULL))
{
temp = temp-> next;
//cout << "TP2" << endl; //TEST POINT
//temp->printname(); cout << endl;
}
if (FirstSkill != NULL)
{
temp->next = nskill;
nskill->next = NULL;
}
}
}
The code that I have is somewhat extensive so I'm only going to include the blocks which are potentially interacting with the function that's throwing up the error.
Thanks in advance for reading through this, and any assistance you're able to offfer, I've been banging my head against this for about 6 hours now and I've lost the perspective to actually track this one down.