This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 8 years ago.
I wrote a c++ code in visual studio 2013 it's working great there.
I need it to work on Ubuntu to , but I get an error
"Undefinded referance Node::Node()"
Node.h
#pragma once
#include "string"
class Node
{
public:
double data;
std::string key;
Node *next;
Node *prev;
Node();
Node(double data , std::string key);
};
Node.cpp
#include <iostream>
#include "Node.h"
Node::Node(){
data = 0;
key = "";
next = NULL;
prev = NULL;
}
Node::Node(double data, std::string key){
this->data = data;
this->key = key;
}
MyLinkedList.h
#pragma once
#include "Node.h"
#include "string"
class MyLinkedList
{
public:
Node *head;
Node *tail;
int size;
MyLinkedList();
MyLinkedList(const MyLinkedList &l);
~MyLinkedList();
bool isEmpty();
void printList();
void add(const std::string key, const double val);
int remove(std::string s);
MyLinkedList& operator=( const MyLinkedList& l);
bool isInList(const std::string key, double &data);
};
MyLinkedList.cpp
#include "MyLinkedList.h"
#include <iostream>
MyLinkedList::MyLinkedList()
{
head = NULL;
tail = NULL;
size = 0;
}
void MyLinkedList::add(const std::string key, double val){
Node *n = new Node(val , key);
if (head == NULL){
head = n;
tail = head;
tail->next = NULL;
}
else{
n->prev = tail;
n->next = NULL;
tail->next = n;
tail = n;
}
++size;
}
MyLinkedList::MyLinkedList(const MyLinkedList &l){
Node *temp = l.head;
while (temp != NULL){
this->add(temp->key, temp->data);
temp = temp->next;
}
}
MyLinkedList::~MyLinkedList()
{
Node *temp = head;
Node *toDelete = temp;
while (temp != NULL)
{
temp = temp->next;
delete toDelete;
toDelete = temp;
}
}
bool MyLinkedList::isEmpty()
{
return head == NULL;
}
void MyLinkedList::printList(){
if (head == NULL){
std::cout << "Empty" << std::endl;
return;
}
Node *temp = head;
while (temp != NULL)
{
std::cout << temp->key <<","<< temp->data << std::endl;
temp = temp->next;
}
}
int MyLinkedList::remove(const std::string s){
Node *p = head;
Node *n = p->next;
int count=0;
while (size > 0 && !head->key.compare(s)){
head = head->next;
delete p;
p = head;
if (p!=NULL)
n = p->next;
--size;
++count;
}
while (size > 0 && n->next != NULL)
{
if (!s.compare(n->key)){
p->next = n->next;
n->next->prev = p;
delete n;
n = p->next;
--size;
++count;
}
else{
p = n;
n = n->next;
}
}
if (size > 0 && !n->key.compare(s)){
n->prev->next = NULL;
delete n;
++count;
--size;
}
return count;
}
MyLinkedList& MyLinkedList::operator = (const MyLinkedList& l){
if (this != &l) {
Node *temp = head;
Node *toDelete = temp;
while (temp != NULL)
{
temp = temp->next;
delete toDelete;
toDelete = temp;
}
temp = l.head;
while (temp != NULL){
this->add(temp->key, temp->data);
temp = temp->next;
}
}
return *this;
}
bool MyLinkedList::isInList(const std::string key, double &data){
Node *temp = head;
while (temp != NULL){
if (!temp->key.compare(key)){
data = temp->data;
return true;
}
}
return false;
}
Simple checks for the MyLinkedList implementation
#include "MyLinkedList.h"
#include <iostream>
#include <string>
int main()
{
MyLinkedList mylist;
std::string firstWord = "aa";
double firstVal = 1.5;
std::string secondWord = "bb";
double secVal = 2.2;
std::string thirdWord = "ab";
double thirdVal = 1.0;
mylist.printList();
std::cout << "Done print list" << std::endl << std::endl;
mylist.add(firstWord, firstVal);
mylist.add(secondWord, secVal);
mylist.add(firstWord, thirdVal);
mylist.add(thirdWord, firstVal);
mylist.printList();
std::cout << "Done print list" << std::endl << std::endl;
return 0;
}
This is all my code. If there is any more differences between Visual Studio and Ubuntu, I would like to know.
copiled with :
g++ -Wall -Werror -Wvla -g ListExample.cpp MyLinkedList.cpp -o ListExample
"Undefined reference" typically means you're missing a .o (object) file or library that contains one of the symbols that your program needs.
For example, if you do
g++ ListExample.cpp
then GCC will try to compile main.cpp straight to an executable and will require that it contain all of the symbols it references.
To compile object files then link multiple object files together, you should instead do something like
g++ -c ListExample.cpp
g++ -c Node.cpp
g++ -c MyLinkedList.cpp
g++ -o linked_list_test ListExample.o Node.o MyLinkedList.o
Writing a Makefile can streamline this for you.
Related
#include <iostream>
using namespace std;
template <typename Object>
struct Node
{
Object data;
Node* next;
Node(const Object &d = Object(), Node *n = (Object)NULL) : data(d), next(n) {}
};
template <typename Object>
class singleList
{
public:
singleList() { init(); }
~singleList() { eraseList(head); }
singleList(const singleList &rhs)
{
eraseList(head);
init();
*this = rhs;
print();
contains(head);
}
void init()
{
theSize = 0;
head = new Node<Object>;
head->next = (Object)NULL;
}
void eraseList(Node<Object> *h)
{
Node<Object> *ptr = h;
Node<Object> *nextPtr;
while (ptr != (Object)NULL)
{
nextPtr = ptr->next;
delete ptr;
ptr = nextPtr;
}
}
int size()
{
return theSize;
}
void print()
{
int i;
Node<Object> *current = head;
for(i=0; i < theSize; ++i){
cout << current->data << " ";
current = current->next;
}
}
bool contains(int x)
{
Node<Object> *current = head;
for (int i = 0; i < theSize; ++i){
if (current->data == x){
return true;
}
current = current -> next;
}
return false;
}
bool add(Object x){
if(!contains(x)){
Node<Object> *new_node = new Node<Object>(x);
new_node->data = x;
new_node->next = head;
head = new_node;
//head->next = new_node;
theSize++;
return true;
}
return false;
}
bool remove(int x)
{
if(contains(x)){
Node<Object> *temp = head;
Node<Object> *prev = NULL;
if(temp != NULL && temp ->data == x){
head = temp->next;
delete temp;
return 0;
}else{
while(temp != NULL && temp->data != x){
prev = temp;
temp = temp->next;
}
if(temp ==NULL){
return 0;
}
prev->next = temp->next;
delete temp;
}
return true;
//theSize--;
}
return false;
}
private:
Node<Object> *head;
int theSize;
};
int main()
{
singleList<int> *lst = new singleList<int>();
lst->add(10);
lst->add(12);
lst->add(15);
lst->add(6);
lst->add(3);
lst->add(8);
lst->add(3);
lst->add(18);
lst->add(5);
lst->add(15);
cout << "The original linked list: ";
lst->print();
cout << endl;
lst->remove(6);
lst->remove(15);
cout << "The updated linked list: ";
lst->print();
cout << endl;
cout << "The number of node in the list: " << lst->size() << endl;
return 0;
}
so the output is supposed to be the following:
The original linked list: 5 18 8 3 6 15 12 10
The update linked list: 5 18 8 3 12 10
The number of node in the list: 6
my output gives the original linked list part but then gives a segmentation fault (core dumped) error. I am not sure where my code is wrong but i think it is in my remove().
Some help will definitely be appreciated.
on line 109 i needed to decrement size.
bool remove(int x)
{
if(contains(x)){
Node<Object> *temp = head;
Node<Object> *prev = NULL;
if(temp != NULL && temp ->data == x){
head = temp->next;
delete temp;
return 0;
}else{
while(temp != NULL && temp->data != x){
prev = temp;
temp = temp->next;
}
if(temp ==NULL){
return 0;
}
prev->next = temp->next;
delete temp;
theSize--;
}
return true;
//theSize--;
}
return false;
}
Answer after second update:
had to fix the remove()
#include <iostream>
using namespace std;
template <typename Object>
struct Node
{
Object data;
Node* next;
Node(const Object &d = Object(), Node *n = (Object)NULL) : data(d), next(n) {}
};
template <typename Object>
class singleList
{
public:
singleList() { init(); }
~singleList() { eraseList(head); }
singleList(const singleList &rhs)
{
eraseList(head);
init();
*this = rhs;
print();
contains(head);
}
void init()
{
theSize = 0;
head = new Node<Object>;
head->next = (Object)NULL;
}
void eraseList(Node<Object> *h)
{
Node<Object> *ptr = h;
Node<Object> *nextPtr;
while (ptr != (Object)NULL)
{
nextPtr = ptr->next;
delete ptr;
ptr = nextPtr;
}
}
int size()
{
return theSize;
}
void print()
{
int i;
Node<Object> *current = head;
for(i=0; i < theSize; ++i){
cout << current->data << " ";
current = current->next;
}
}
bool contains(int x)
{
Node<Object> *current = head;
for (int i = 0; i < theSize; ++i){
if (current->data == x){
return true;
}
current = current -> next;
}
return false;
}
bool add(Object x){
if(!contains(x)){
Node<Object> *new_node = new Node<Object>(x);
new_node->data = x;
new_node->next = head;
head = new_node;
//head->next = new_node;
theSize++;
return true;
}
return false;
}
bool remove(int x){
Node<Object> *pCur = head;
Node<Object> *pPrev = pCur;
while (pCur && pCur->data != x) {
pPrev = pCur;
pCur = pCur->next;
}
if (pCur==nullptr) // not found
return false;
if (pCur == head) { // first element matches
head = pCur->next;
} else {
pPrev->next = pCur->next;
}
// pCur now is excluded from the list
delete pCur;
theSize--;
return true;
}
private:
Node<Object> *head;
int theSize;
};
int main()
{
singleList<int> *lst = new singleList<int>();
lst->add(10);
lst->add(12);
lst->add(15);
lst->add(6);
lst->add(3);
lst->add(8);
lst->add(3);
lst->add(18);
lst->add(5);
lst->add(15);
cout << "The original linked list: ";
lst->print();
cout << endl;
lst->remove(6);
lst->remove(15);
cout << "The updated linked list: ";
lst->print();
cout << endl;
cout << "The number of node in the list: " << lst->size() << endl;
return 0;
}
I am facing a problem while coding Linked List implementation in c++. Whenever I am trying to add an element he following code doesn't show any output. What's wrong with the code
#include<iostream>
using namespace std;
struct Node {
int data;
struct Node* ptr;
Node(int val) {
data = val;
ptr = NULL;
}
};
void addItem(struct Node* head, int val) {
struct Node* n = new Node(val);
if(head == NULL){
head = n;
return;
}
struct Node* cur = head;
while(cur->ptr != NULL){
cur = cur->ptr;
}
cur->ptr = n;
}
void printList(struct Node* head) {
struct Node* cur = head;
while(cur != NULL) {
cout << cur->data << " ";
cur = cur->ptr;
}
}
int main() {
struct Node* head = NULL;
addItem(head, 1);
addItem(head, 2);
addItem(head, 3);
addItem(head, 4);
printList(head);
return 0;
}
When I run the program it shows nothing on the terminal.
Output:
[Running] cd "c:\Users\Sonu\" && g++ LinkedList.cpp -o LinkedList && "c:\Users\Sonu\"LinkedList
[Done] exited with code=0 in 3.436 seconds
You should pass head by double pointer or by reference. Otherwise it will be just a copy on function argument which will get destroyed when coming out of the function.
void addItem(Node** head, int val) {
Node* n = new Node(val);
if(*head == NULL){
*head = n;
return;
}
Node* cur = *head;
while(cur->ptr != NULL){
cur = cur->ptr;
}
cur->ptr = n;
}
// ...
addItem(&head, 1); // take the address with &
or
void addItem(Node*& head, int val) {
Node* n = new Node(val);
if(head == NULL){
head = n;
return;
}
Node* cur = head;
while(cur->ptr != NULL){
cur = cur->ptr;
}
cur->ptr = n;
}
// ...
addItem(head, 1); // no change needed
"dlist_test.cc:16: error: 'testList' was not declared in this scope.
dlist_test.cc:16: error: 'Dlist' was not declared in this scope."
I have been looking at other threads on circular dependences or namespace but I only have one header file, and I'm not using a namespace for dlist.h or dlist.cc. Where am I not declaring this correctly? Is it a Makefile problem? Any help would be appreciated, thank you for your time.
dlist.h:
#ifndef DLIST_H
#define DLIST_H
struct ListNode
{
/* define your list node type */
int val;
ListNode* next;
ListNode* prev;
};
class DList
{
public:
DList();
/* implement copy constructor, assignment, destructor if needed */
void add_to_front(int value);
void add_to_back(int value);
int first();
int last();
void remove(ListNode* node);
ListNode* previous(ListNode* node);
ListNode* next(ListNode* node);
ListNode* search_value(int value);
private:
/* declare your data */
ListNode* head;
ListNode* tail;
};
#endif
dlist.cc
#include "dlist.h"
#include <cstddef>
#include <stdlib.h>
class Dlist{
public:
Dlist(){
head = NULL;
tail = NULL;
}
void add_to_front(int value){
struct ListNode* newhead = (struct ListNode*) malloc(sizeof(struct ListNode));
newhead->val = value;
newhead->prev = NULL;
newhead->next = head;
if(head != NULL)
head->prev = newhead ;
head = newhead;
}
void add_to_back(int value){
if (tail == NULL){
struct ListNode* firstValue = (struct ListNode*)malloc(sizeof(ListNode));
firstValue->val = value;
firstValue->prev = NULL;
firstValue->next = NULL;
tail = firstValue;
}else{
struct ListNode* newtail = (struct ListNode*)malloc(sizeof(ListNode));
newtail->val = value;
newtail->next = NULL;
newtail->prev = tail;
tail->next = newtail;
tail = newtail;
}
}
int first(){
return head->val;
}
int last(){
return tail->val;
}
void remove(ListNode* node){
if (head == NULL || node == NULL){
return;
}
if(head == node){
head = node->next;
}
if (node->next != NULL){
node->next->prev = node->prev;
}
if (node->prev != NULL){
node->prev->next = node->next;
}
free(node);
}
ListNode* previous(ListNode* node){
if(node->prev != NULL){
return node->prev;
}
}
ListNode* next(ListNode* node){
if(node->next != NULL){
return node->next;
}
}
ListNode* search_value(int value){
while(head->next != NULL){
if(head->next->val == value){
return head;
}else{
head = head->next;
}
}
}
private:
ListNode* head;
ListNode* tail;
};
dlist_test.cc
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "dlist.h"
#include <bits/stdc++.h>
using namespace std;
int main (int argc, char* argv[])
{
int N = -1;
if (argc == 2) {
N = atoi (argv[1]);
assert (N > 0);
}
testList = Dlist();
int i = 0;
while(i<N){
testList.add_to_back(i+1);
i++;
}
int randn = rand() % N + 1;// randn in the range 1 to N
//
time_t start, end;
time(&start);
ios_base::sync_with_stdio(false);
struct ListNode* loc = testList.search_value(randn);
testList.remove(loc);
time(&end);
double time_taken = double(end - start);
cout << "Time taken by program is : " << fixed
<< time_taken << setprecision(5);
cout << " sec " << endl;
//
testList.add_to_front(N);
return 0;
}
Makefile:
default:
#echo "=================================================="
#echo "To build your sorting code, use:"
#echo "make dlist_test or make queue_test"
#echo "=================================================="
# Queue driver
queue_test: queue.o
# Doubly linked list driver
dlist_test: dlist.o dlist_test.o
g++ -o dlist_test dlist.o dlist_test.o
dlist.o: dlist.cc dlist.h
g++ -c dlist.cc
dlist_test.o: dlist_test.cc
g++ -c dlist_test.cc
clean:
rm -f core *.o *~ queue_test dlist_test
# eof
These are two different problems:
1) C++ distinguishes uppercase letters from lowercase ones. You declared the class as DList so you need write this name exactly this way. Dlist (with lower case "L") is considered an entirely different name.
2) You've never created variable testList so C++ is right to tell that it doesn't exist. It happens to the best ;)
Just change the line
testList = Dlist();
to
Dlist testList = Dlist();
or
Dlist testList;
The both variants are equivalent. C++ will use a constructor without parameters by default.
this is my lab and I work all of it. After long time of debugging, fixing errors, finally it can compile. But when it run, it didn't give me the correct answer. It just kept saying : did not find y (may be x was added) and it was 4 line with the same answer.
please look at my code and tell me why it didn't work.
Thanks a lot.
Here is my code:
LinkedList.h:
#ifndef _LINKED_LIST_
#define _LINKED_LIST_
#include <ostream>
class LinkedList
{
public:
LinkedList();
LinkedList(char ch);
LinkedList(const LinkedList& List);
~LinkedList();
void add(const char& ch);
bool find(char ch);
bool del(char ch);
friend std::ostream& operator<<(std::ostream& out, LinkedList& list);
private:
struct node
{
char item;
node * next;
};
node * head;
int size;
};
#endif // _LINKED_LIST_
Linkedlist.cpp
#include "linkedlist.h"
#include <iostream>
#include <fstream>
#include <cassert>
#include <cstring>
using namespace std;
LinkedList::LinkedList() : head(NULL)
{
}
LinkedList::LinkedList(char ch):head(NULL)
{
char currData;
currData = ch;
add(currData);
}
LinkedList::~LinkedList()
{
node * curr = head;
while(head)
{
curr = head->next;
delete head;
head = curr;
}
}
LinkedList::LinkedList(const LinkedList& List)
{
if(List.head == NULL)
head = NULL;
else
{
//copy first node
head = new node;
assert(head != NULL);
head->item = List.head->item;
//copy the rest of the list
node * destNode = head; //points to the last node in new list
node * srcNode = List.head->next; //points to node in aList
while(srcNode != NULL) //or while (srcNode)
{
destNode->next = new node;
assert(destNode->next != NULL); //check allocation
destNode = destNode->next;
destNode->item = srcNode->item;
srcNode = srcNode->next;
}
destNode->next = NULL;
}
}
ostream& operator<<(std::ostream& out, LinkedList& list)
{
while(list.head)
{
out << list.head->item << endl;
list.head = list.head->next;
}
return out;
}
void LinkedList::add(const char& ch)
{
node * prev = NULL;
node * curr = head;
while (curr != NULL && curr->item < ch)
{
prev = curr;
curr = curr->next;
}
if (curr && curr->item != ch)
{
node * newNode = new node;
newNode->item = ch;
newNode->next = NULL;
newNode->next = curr;
if (prev == NULL)
head = newNode;
else
prev->next = newNode;
size++;
}
}
bool LinkedList::del(char ch)
{
char a;
node * prev = NULL;
node * curr = head;
while (curr)
{
a = curr->item;
if ( a == ch)
{
if(!prev)
head = curr->next;
else
prev->next = curr->next;
delete curr;
size--;
return true;
}
prev = curr;
curr = curr->next;
}
return false;
}
bool LinkedList::find(char ch)
{
char a;
node * prev = NULL;
node * curr = head;
while (curr)
{
a = curr->item;
if ( a == ch)
{
return true;
}
prev = curr;
curr = curr->next;
}
return false;
}
app.cpp
#include <iostream>
#include "linkedlist.h"
using namespace std;
void find(LinkedList& list, char ch)
{
if (list.find(ch))
cout << "found ";
else
cout << "did not find ";
cout << ch << endl;
}
int main()
{
LinkedList list;
list.add('x');
list.add('y');
list.add('z');
cout << list;
find(list, 'y');
list.del('y');
cout << list;
find(list, 'y');
list.del('x');
cout << list;
find(list, 'y');
list.del('z');
cout << list;
find(list, 'y');
return 0;
}
Your add method doesn't work, if the item to insert goes at the end it is not inserted (because you are checking for curr == NULL before inserting). Since head is set to NULL when you create the list if(curr && ...) won't ever be true and no item will be inserted.
when building the project in Visual Studio 2013 the message:
Unhandled exception at 0x00CD5154 in prj.exe: 0xC0000005: Access violation writing location 0x00000004
Please help. It's actualy an example https://www.youtube.com/watch?v=3gZ7F31Mwi0 I write almost the same.
Header.h
#ifndef HEADER_H_
#define HEADER_H_
#include <iostream>
#include <string>
//#include <iostream>
//#include <vector>
typedef struct Node
{
int data;
Node* link;
}* NodePtr;
class List
{
public:
List();
~List();
int numberOfElements();
NodePtr getPointer(const int node_number) const;
void addNode(int data_);
//NodePtr head;
private:
NodePtr head;
NodePtr curr;
NodePtr temp;
NodePtr start_index;
};
#endif // !HEADER_H_
Source.cpp
#include "Header.h"
List::List()
{
head = NULL;
curr = NULL;
temp = NULL;//head_ptr = this->Nodes;
start_index = NULL;
}
List::~List()
{
}
int List::numberOfElements()
{
size_t i = 0;
temp = start_index;
while (temp->link != NULL)
{
temp = temp->link;
i++;
}
return i;
}
NodePtr List::getPointer(const int node_number) const
{
NodePtr counter = start_index;
for (size_t i = 0; i < node_number; i++)
{
//%
std::cout << i << std::endl;
//%
if (counter == NULL)
{
std::cout << "last index is " << i << std::endl;
return counter;
}
counter = counter->link;
}
return counter;
}
void List::addNode(int data_)
{
NodePtr n = new Node;
n->data = data_;
n->link = NULL;
if (head != NULL)
{
curr = head;
while (curr != NULL)
curr = curr->link;
curr->link = n;
}
else
{
head = n;
start_index = n;
}
}
main.cpp
#include "Header.h"
int main()
{
using namespace std;
List one;
one.addNode(1);
one.addNode(2);
one.addNode(3);
//cout << (*one.head).data << endl;
//cout << one.getPointer(1)->data << endl;
cin.get();
}
After the loop
while (curr != NULL)
curr = curr->link;
curr will be NULL (think about this until you realise why it is true).
Thus, the line
curr->link = n;
where you dereference the null pointer is invalid.
You want
while (curr->link != NULL)
curr = curr->link;