I am having some trouble with my school project. I think that it may be an error with my use of pointers but I am not sure why I am getting this error. This code is incomplete but I am trying to test it along the way. Do you have any idea why I am getting this error and what does it mean? Thanks!
Error from Cygwin Terminal
-bash-3.2$ make clean
rm -rf *.o simulate
-bash-3.2$ make simulate
g++ -c -g Main.cpp
g++ -c -g Maze.cpp
g++ Main.o Maze.o -o simulate
/usr/bin/ld: Dwarf Error: found dwarf version '4', this reader only handles version 2 information.
Maze.o: In function `Maze::createMaze(char*)':
Maze.cpp:(.text+0x49): undefined reference to `Node::Node(char)'
collect2: error: ld returned 1 exit status
make: *** [simulate] Error 1
Main.cpp
#include <iostream>
#include <fstream>
#include <string>
#include "Maze.h"
using namespace std;
int main()
{
int array_size = 1024;
char * mazeArray = new char[array_size];
int position = 0;
string mazeName;
Maze Maze1;
cout << "Enter the name of the maze file: ";
getline(cin, mazeName);
ifstream fin(mazeName.c_str());
//File opened successfully
if(fin.is_open())
{
while(!fin.eof() && position < array_size)
{
fin.get(mazeArray[position]); //reading one character from file to mazeArray
position++;
}
mazeArray[position-1] = '\0'; //placing character mazeArray terminating character
for(int i = 0; mazeArray[i] != '\0'; i++){
if(isspace(mazeArray[i]))
mazeArray[i] = mazeArray[i+1];
}
cout << "Displaying mazeArray..." << endl << endl;
//this loop display all the charaters in mazeArray till \0
for(int i = 0; mazeArray[i] != '\0'; i++)
{
cout << mazeArray[i];
}
cout << endl;
Maze1.createMaze(mazeArray);
}
else //file could not be opened
{
cout << "File could not be opened." << endl;
}
return 0;
}
Maze.h
#ifndef MAZE_H
#define MAZE_H
#include <string>
#include <sstream>
#include <vector>
#include "Node.h"
using namespace std;
class Maze
{
public:
void createMaze(char*);
void availablePaths();
void displayPath();
void moveNorth();
void moveSouth();
void moveEast();
void moveWest();
int getroomCount();
char getpathHistory();
char getcurrentRoom();
private:
int roomCount;
char pathHistory[];
Node* currentRoom;
Node* nodeArray[12];
struct isPath;
vector<Node*> nodeVector;
};
#endif
Maze.cpp
#include <iostream>
#include <string>
#include "Maze.h"
using namespace std;
Node* Node1;
void Maze::createMaze(char *inFile){
int count = 0;
//Creates Nodes for Maze
for(int ii = 0; ii <= 12; ii++){
Node1 = new Node(inFile[count]);
nodeVector.push_back(Node1);
count = count + 5;
//If there is not another node break out of the for loop.
if(inFile[count] == '\0'){
break;
}
}
}
void Maze::availablePaths(){
}
void Maze::displayPath(){
}
void Maze::moveNorth(){
}
void Maze::moveSouth(){
}
void Maze::moveEast(){
}
void Maze::moveWest(){
}
int Maze::getroomCount(){
}
char Maze::getpathHistory(){
}
char Maze::getcurrentRoom(){
}
Node.h
#ifndef NODE_H
#define NODE_H
#include <string>
#include <map>
#include <sstream>
using namespace std;
class Node
{
public:
Node(char);
void setNodeName(char);
void attachNewNode(Node, int);
Node *getAttachedNode(int);
private:
char name; // Title that is displayed above the menu.
Node *attachedNodes[4];
};
#endif
Node.cpp
#include <iostream>
#include <string>
#include <vector>
#include "Node.h"
using namespace std;
Node::Node(char name) : name(name) {
}
void Node::setNodeName(char tempName){
name = tempName;
}
void Node::attachNewNode(Node temp, int direction){
attachedNodes[direction] = temp;
}
Node Node::getAttachedNode(int direction){
return attachedNodes[direction];
}
makefile
#!/bin/bash
#file:makefile
CC = g++
CFLAGS = -c -g
simulate: Main.o Maze.o
$(CC) Main.o Maze.o -o simulate
Main.o: Main.cpp Maze.h
$(CC) $(CFLAGS) Main.cpp
Maze.o: Maze.cpp Menu.h Node.h
$(CC) $(CFLAGS) Maze.cpp
Node.o: Node.cpp Node.h
$(CC) $(CFLAGS) Node.cpp
clean:
rm -rf *.o simulate
The problem is not in your code, per se.
One problem is that your linking command is failing because you are not linking all your object files. You need to link Main.o, Maze.o and Node.o to create the executable:
g++ Main.o Maze.o Node.o -o simulate
Another problem is that your compiler is newer than your linker. The compiler is generating debugging information using Dwarf version 4, but your linker (/usr/bin/ld) only understands Dwarf version 2.
/usr/bin/ld: Dwarf Error: found dwarf version '4', this reader only handles
version 2 information.
You need to update your linker to a newer version compatible with the compiler you are using.
Or, as janneb suggests in a comment, you can use -gdwarf-2 in both the compilation and link lines. In the makefile:
CFLAGS = -c -gdwarf-2
FILES.cpp = Main.cpp Maze.cpp Node.cpp
FILES.o = $(FILES.cpp:.cpp=.o}
simulate: $(FILES.o)
$(CC) $(CFLAGS) $(FILES.o) -o $#
(There should be few parts of command lines in a makefile that are not macro invocations; then you can change everything more easily.)
You will need to remove the Dwarf-4 object files and recompile to avoid the error/warning.
You can simply fix this by:
export CFLAGS='-gdwarf-2 -gstrict-dwarf'
Then, remake your project.
Related
I'm working on a testing program for a lab and I keep getting the error
[jereminp#bondi hw3]$ make insert_test
g++ -O3 -g -o insert_test.o -c insert_test.cc
g++ -O3 -g -o insert_test insert_test.o
insert_test.o: In function `main':
/users/ugrad/2018/fall/jereminp/114/hw3/hw3/insert_test.cc:17: undefined reference to `HashTable::HashTable()'
/users/ugrad/2018/fall/jereminp/114/hw3/hw3/insert_test.cc:24: undefined reference to `HashTable::insert(int)'
/users/ugrad/2018/fall/jereminp/114/hw3/hw3/insert_test.cc:32: undefined reference to `HashTable::insert(int)'
collect2: ld returned 1 exit status
make: *** [insert_test] Error 1
I'm fairly certain I have the logic, but I can't get past this error and I feel like I'm missing something simple. Here's the parts of the code in question.
Makefile
CC = g++
CFLAGS =
COPTFLAGS = -O3 -g
insert_test: insert_test.o
$(CC) $(COPTFLAGS) -o $# $^
insert_test.cc
#include "HashTable.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
class HashTable;
int main(int argc, char* argv[])
{
//checks .5 and .9 1x
int numRuns = 0;
int numProbes = 0;
int a=0;
HashTable h;
HashTable.hh
#ifndef HASHTABLE_H
#define HASHTABLE_H
class HashTable
{
public:
HashTable();
/* implement copy constructor, assignment, destructor if needed */
int hashfnc(int key);
int insert (int value);
/* insert the input value and return the number of probes
* return -1 if the table is full and insert fails */
bool find (int value, int& nProbes);
/* Search for the input value in table
* Return true if the search is successful, otherwise false
* Save # probes in 'nProbes' */
// getters
int capacity() { return nSlot; }
int size() { return nElem; }
double load_factor() { return load; }
int getSearchProbes() { return probesSearch; }
private:
/* declare your data */
double load; // track the load factor of table
int nSlot; // # slots i.e. max # elements can hold
int nElem; // current # elements in table
int arr[];
int probesSearch;
};
#endif
HashTable.cc
#include "HashTable.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
class HashTable
{
public:
HashTable()
{
load = 0;
nSlot = 300;//nSlot is changable in order to optimize
nElem = 0;
arr = new int[nSlot];
probesSearch=0;
for(int i = 0;i<nSlot;i++)
{
arr[i] = NULL;
}
}
Some of the things I've tried are adding any and all includes I could think of, changing the last line shown in insert_test.cc to "HashTable h = new HashTable();"(where I got a different error), adding namespace std to the header. I feel like it should be a quick fix but at the same time I can't find the solution anywhere. Plz send help
I am using the C++ standard library in some C++ code and this makefile:
CC=g++
CXXFLAGS=-Wall -Werror -ggdb3 -std=c++11 -pedantic $(OTHERFLAGS)
cpp_sort: cpp_sort.o
g++ -o $# $(CXXFLAGS) $^
clean:
rm -rf *.o cpp_sort *~
The source code:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void get_input(vector<int>& items, int size) {
for (int i = 0; i < size; ++i) {
int element;
cin >> element;
items.push_back(element);
}
}
void cpp_sort(vector<int>& items) {
sort(items.begin(), items.end());
}
void print_array(vector<int>& items) {
for (auto& item : items) {
cout << item << ' ';
}
cout << endl;
}
int main() {
int size;
cin >> size;
vector<int> items;
items.reserve(size);
get_input(items, size);
cpp_sort(items);
print_array(items);
}
I call make like this:
make OTHERFLAGS=-pg
run the program (where large.txt is a long list of integers):
./cpp_sort <large.txt
and view the profiling information:
grof ./cpp_sort
Which is fine and it does work, but the calling of my functions is obscured by all the C++ standard library function calls. Is there a way to exclude the standard library internal function calls?
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 5 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
I've been writing a program that populates a deck of cards. I'm using a makefile to build the executable but keep getting a segmentation fault when I execute. Can someone please take a look at the code below and point out where the error is coming from?
Thanks!
Card.h
#ifndef CARD_H
#define CARD_H
#include <iostream>
class Card
{
public:
Card(char rankSet, char suitSet);
Card();
private:
char rank, suit;
};
#endif
Card.cpp
#include "Card.h"
Card::Card()
{
rank = 'A';
suit = 'C';
}
Card::Card(char rankSet, char suitSet)
{
rank = rankSet;
suit = suitSet;
}
Deck.h
#ifndef DECK_H
#define DECK_H
#include <iostream>
#include "Card.h"
class Deck
{
public:
Deck();
private:
Card *deckOfCards;
};
#endif
Deck.cpp
#include "Deck.h"
Deck::Deck()
{
char ranks[13] = {'A','2','3','4','5','6','7','8','9','T','J','Q','K'};
char suits[4] = {'C','D','H','S'};
deckOfCards = new Card[52];
int k = 0;
for(int i = 0; i<13; i++)
{
for(int j=0; j<4; i++)
{
deckOfCards[k] = Card(ranks[i],suits[j]);
k++;
}
}
}
Main.cpp
#include "Deck.h"
int main()
{
Deck deck1;
return 0;
}
Makefile
#
CC = g++
CFLAGS = -g -Wall -lm
#
default: Main
# To create the executable file count we need the object files
Main: Main.o Card.o Deck.o
$(CC) $(CFLAGS) -o Main main.o Card.o Deck.o
# To create the object file
Main.o: main.cpp Deck.h Card.h
$(CC) $(CFLAGS) -c main.cpp
# To create the object file
Deck.o: Deck.cpp Deck.h Card.h
$(CC) $(CFLAGS) -c Deck.cpp
# To create the object file
Card.o: Card.cpp Card.h
$(CC) $(CFLAGS) -c Card.cpp
clean:
$(RM) Main *.o *~
You increment i instead of j inside the for loop
EDIT: Answered -- the issue was that because the functions had the same signature, despite them being in separate files, C++ saw both versions and got confused.
I have three classes: Table and Bed both inherit from Furniture.
Table and Bed each have a helper function GetLowerCase(std::string) defined in each class individually. When make is run (Makefile shown below), I get an error saying that GetLowerCase in Bed.cpp was first defined in Table.cpp
Makefile:
main: main.o Furniture.o Table.o Bed.o
g++ main.o Furniture.o Table.o Bed.o -o main
main.o: main.cpp
g++ -c main.cpp
Furniture.o: Furniture.cpp Furniture.h
g++ -c Furniture.cpp
Table.o: Furniture.cpp Table.cpp Table.h
g++ -c Table.cpp
Bed.o: Furniture.cpp Bed.cpp Bed.h
g++ -c Bed.cpp
clean:
rm *.o main
Table.cpp:
#include "Table.h"
#include <iostream>
#include <string>
std::string GetLowerCase(std::string str)
{
std::string out;
for (int i=0; i<str.length(); i++)
{
out[i] = tolower(str[i]);
}
return out;
}
Table::Table(const std::string n, std::string wt) : Furniture(n)
{
wood_type = GetLowerCase(wt);
if (wood_type != "pine" && wood_type != "oak")
{
std::cerr << "Wood type must be OAK or PINE.";
}
}
void Table::Print()
{
Furniture::Print();
std::cout << "Wood Type: " << wood_type << std::endl;
}
Bed.cpp:
#include "Bed.h"
#include <iostream>
#include <string>
std::string GetLowerCase(std::string str)
{
std::string out;
for (int i=0; i<str.length(); i++)
{
out[i] = tolower(str[i]);
}
return out;
}
Bed::Bed(const std::string n, std::string sz) : Furniture(n)
{
size = GetLowerCase(sz);
if (size != "twin" && size != "full" && size != "queen" && size != "king")
{
std::cerr << "Bed size must be TWIN, FULL, QUEEN, or KING.";
}
}
void Bed::Print()
{
Furniture::Print();
std::cout << "Size: " << size << std::endl;
}
I would have thought that GetLowerCase would be entirely contained within the .cpp file it was defined in and wouldn't be "seen" by any other files.
It's not in any header or source files besides the two listed above. Very confused, and would love some help!
Either declare your function static or wrap it in an anonymous namespace:
namespace {
// duplicated names here.
}
Your options:
Move all your helper functions into a helper class (like CommomUtils) as static member functions. I recommend this way, it's more C++, and you can avoid duplicate code.
Declare your function as static. So its scope would be in file that defines it, rather than global.
Warp your function with namespace.
Defines your function only once, and in file you want to use it, use extern std::string GetLowerCase(std::string str) to declare it, then you can call it.
I'm creating a queue class in c++ and am having trouble compiling with a makefile. My queue.cpp class is here
#include "queue.h"
#include <stdlib.h>
queue::queue()
{
front_p = NULL;
back_p = NULL;
current_size = 0;
}
void queue::enqueue(int item)
{
node newnode = node(item, NULL);
if (front_p == NULL) //queue is empty
{
front_p = &newnode;
back_p = &newnode;
}
else
{
back_p->next = &newnode;
back_p = &newnode;
}
current_size ++;
}
My header file (queue.h) is here
class queue
{
public:
queue(); // constructor - constructs a new empty queue.
void enqueue( int item ); // enqueues item.
int dequeue(); // dequeues the front item.
int front(); // returns the front item without dequeuing it.
bool empty(); // true iff the queue contains no items.
int size(); // the current number of items in the queue.
int remove(int item); // removes all occurrances of item
// from the queue, returning the number removed.
private:
class node // node type for the linked list
{
public:
node(int new_data, node * next_node ){
data = new_data ;
next = next_node ;
}
int data ;
node * next ;
};
node* front_p ;
node* back_p ;
int current_size ; // current number of elements in the queue.
};
test program (tester.cpp)
#include <iostream>
#include "queue.h"
#include <stdlib.h>
using namespace std;
int main(int argc, char * const argv[])
{
cout << "Lalalalala" << endl;
queue q1;
q1.enqueue(5);
}
makefile
all: tester
tester: queue.o
g++ -o tester tester.cpp
queue.o: queue.cpp queue.h
g++ -c queue.cpp
clean:
rm -f tester *.o
when I type "make" or "make all" I get this error:
g++ -o tester tester.cpp
/tmp/ccTOKLWU.o: In function `main':
tester.cpp:(.text+0x33): undefined reference to `queue::queue()'
tester.cpp:(.text+0x44): undefined reference to `queue::enqueue(int)'
collect2: ld returned 1 exit status
make: *** [tester] Error 1
The unusual thing about it, is that when compiled in visual studio on a windows machine, there are no errors. I haven't the faintest idea why it shouldn't compile on a linux machine in the way I am doing so. Would anyone kindly explain?
Your makefile is incorrect - it compiles tester.cpp with a dependency on queue.o, but it does not link queue.o at all. That is why the compilation of tester.cpp results in an unresolved reference.
You should change your make file as follows:
all: tester
tester: queue.o tester.o
g++ queue.o tester.o -o tester
tester.o: tester.cpp tester.h
g++ -c tester.cpp
queue.o: queue.cpp queue.h
g++ -c queue.cpp
clean:
rm -f tester *.o