"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.
Related
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
This is my code for an implementation of a doubly linked list that inherits previous code from a single linked list, I am currently having trouble with a linker error and surfed the web for the past hour looking for an answer to my problem and found nothing so far to help me. This is my last resor can anyone help?
Specifically the error i get when i try to use g++ to link my .o files is:
DoublyList.o:DoublyList.cpp:(.text+0xf): undefined reference to
`LinkedList::LinkedList()'
collect2.exe: error: ld returned 1 exit status
I have found very similar questions asked but none of the answers helped me or at least I do not know how to implement them in my code specifically, any help will be apprectiated.
My LinkedList class
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
using namespace std;
struct node
{
float value;
node *next;
};
class LinkedList
{
private:
node *first;
public:
LinkedList();
virtual void insert(float val);
virtual void del(float val);
virtual void read();
virtual int search(float val);
};
#endif
My LinkedList class definition
#include <iostream>
#include "LinkedList.h"
using namespace std;
LinkedList::LinkedList()
{
this->first = NULL;
}
void LinkedList::insert(float val)
{
if(this->first==NULL or this->first->value >= val)
{
node* a_node = new node();
a_node->value = val;
this->first = a_node;
return;
}
node* n = new node();
n = this->first;
node* new_node = new node();
new_node->value = val;
while(n->next != NULL and n->next->value < new_node->value)
{
n = n->next;
}
new_node->next = n->next;
n->next = new_node;
}
void LinkedList::del(float val)
{
node* n = this->first;
node* prev = new node();
prev = n;//in case if it is the first value
int i = this->search(val);
if(this->first->value == val)
{
this->first = this->first->next;
return;
}
if(i != -1)
{
for(int j = 0; j < i; j++)
{
prev = n;
n = n->next;
}
}
//one last check
if(n->value == val)
{
prev->next = n->next;
}
}
void LinkedList::read()
{
node* n = this->first;
int i = 1;
while(n != NULL)
{
cout << i << ". " << n->value << endl;
n = n->next;
i++;
}
}
int LinkedList::search(float val)
{
int i = 0;
node* n = this->first;
while(n != NULL)
{
if(n->value == val)
return i;
else
{
n = n->next;
i++;
}
}
return -1;
}
My doublylist class
#ifndef DOUBLYLIST_H
#define DOUBLYLIST_H
#include "LinkedList.h"
class DoublyList: public LinkedList
{
public:
struct node
{
float value;
node * next;
node * prev;
};
node * first;
DoublyList();
void insert(float val);
void del(float val);
void read();
int search(float val);
};
#endif
My Doubly List definiton
#include <cstddef>
#include "DoublyList.h"
#include "LinkedList.h"
using namespace std;
//constructor
DoublyList::DoublyList()
{
first = NULL;
}
//Insert a node into the correct position in the doubly linked list
void DoublyList::insert(float val)
{
//if linked list is empty or val <= the first node
if(this->first == NULL or this->first->value >= val)
{
node * a_node = new node();
a_node->value = val;//set node's value
//begin replacing and assigning pointers
a_node->next = this->first;
a_node->prev = NULL;
this->first = a_node;
return;
}
node * n = new node();
n = this->first;
node * new_node = new node();
new_node->value = val;
node * prev_node = new node();
while(n->next != NULL and n->next->value < new_node->value)
{
prev_node = n;
n = n->next;
}
prev_node->next = new_node;
new_node->next = n->next;
new_node->prev = prev_node;
n->next = new_node;
}
void DoublyList::del(float val)
{
node * n = this->first;
int i = this->search(val);
//if first node
if(this->first->value == val)
{
this->first = this->first->next;
this->first->prev = NULL;
return;
}
//if value found
if(i != -1)
{
for(int j = 0; j < i; j++)
{
n = n->next;
}
//if a middle node
if(n->value == val and n->next != NULL)
{
n->prev->next = n->next;
return;
}
//if last node
if(n->prev != NULL)
{
n->prev->next = n->next;
}
}
return;//value not found so return
}
void DoublyList::read() { }
int DoublyList::search(float val) { }
Edit: Forgot to mention this error specifically happens aruond line 8 of DoublyList.cpp, this was from previous trials to link the .o files.
The command I used to call the linker is
g++ -g main2.cpp DoublyList.o
Where main2.cpp is the code that contains my main function to test the code.
Thanks to xskxzr the solution was to also link LinkedList.o along with all the rest of the .o files. If anyone ever has the same problem this is the answer.
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.
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.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I implement a queue myself. when testing, I expect the dequeue to reutrn when the queue is empty by testing if the tail pointer point to the head node. However, the address of the head node and the one pointer point are different when the point indeed points to the head, hence the queue never stop dequeue even if there is nothing in it.
This confuse me a lot. Any suggestion on this?
thanks a lot.
//header
#ifndef QUEUE_H
#define QUEUE_H
struct node
{
int val;
struct node* next;
};
class queue
{
private:
node head;
node* tail;
public:
queue();
void enqueue(int val);
void dequeue(int& holder, bool& v);
};
#endif
// queue.cpp
#include "queue.h"
using namespace std;
queue::queue()
{
tail = &head;
}
void queue::enqueue(int val)
{
node* tmp = new node;
tmp->val = val;
if(tail == &head)
{
tail = tmp;
tmp->next = &head;
head.next = tmp;
}
else
{
node* holder = head.next;
head.next = tmp;
tmp->next = &head;
holder->next = tmp;
}
}
void queue::dequeue(int& holder,bool& v)
{
if(tail == &head)
{
v = false;
}
else
{
node* cur = tail;
tail = tail->next;
holder = cur->val;
v = true;
delete cur;
}
}
//test.cpp
#include <iostream>
#include "queue.h"
using std::cout;
using std::endl;
int main()
{
int ary[] = {1,2,3,4,5};
queue myq;
for(int i = 0;i< sizeof(ary);i++)
{
myq.enqueue(ary[i]);
}
int tmp;
bool flag;
for(int i = 0;i<=7;i++)
{
myq.dequeue(tmp,flag);
if(flag)
cout<<"number is "<<tmp<<endl;
else
cout<<"queue empty"<<endl;
}
return 0 ;
}
I could give you the exact fix, but that would teach you absolutely nothing, you'd just copy and paste that into your code and go away do something else. So I'm going to help you with a line of code to add to show what the current value of &head is, and thus help identify what the actual problem is...
Add this line to enqueue (at the top of the function) and dequeue:
std::cout << __FUNCTION__ << ": " << &head << std::endl;
It will print the name of the function and the address off head. (You may need to include iostream as well)
Pay particular attention to how many printouts you get!
Working code below: (Learn to use a debugger)
#include <iostream>
using namespace std;
//header
#ifndef QUEUE_H
#define QUEUE_H
struct node {
int val;
struct node* next;
};
class queue {
private:
struct node* head;
struct node* tail;
public:
queue();
void enqueue(int val);
void dequeue(int& holder, bool& v);
};
#endif
using namespace std;
queue::queue() {
tail = NULL;
head = NULL;
}
void queue::enqueue(int val) {
node* tmp = new node;
tmp->val = val;
if (head == NULL && NULL == tail) {//No nodes Empty
head = tail = tmp;
tmp->next = NULL;
}else if (tail == head) { //Single node
tail = tmp;
tmp->next = head;
head->next = tmp;
} else {
tail->next = tmp;
tmp->next = head;
tail = tmp;
}
}
void queue::dequeue(int& holder, bool& v) {
if (NULL == tail || NULL == head) {
v = false;
return;
} else if (tail == head) {// single node
holder = head->val;
delete head;
head = NULL;
tail = NULL;
v = true;
} else { //more than one node
//Go to the last but one node and chop the tail
node* cur = head;
while (cur->next != tail)
cur = cur->next;
cur->next = head;
holder = tail->val;
delete tail;
tail = cur;
v = true;
}
return;
}
using std::cout;
using std::endl;
int main() {
int ary[] = { 1, 2, 3, 4, 5 };
queue myq;
for (int i = 0; i < 5; i++) {
myq.enqueue(ary[i]);
}
int tmp;
bool flag;
for (int i = 0; i <= 7; i++) {
myq.dequeue(tmp, flag);
if (flag) {
cout << "number is " << tmp << endl;
}
else {
cout << "queue empty" << endl;
}
}
return 0;
}