So I've run into this compiling error when I put the following:
bash-3.2$ g++ -o a *.cpp
Undefined symbols for architecture x86_64:
"set_function::set_function(int)", referenced from:
_main in ccezs7Gk.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
but it seems as though everything is right in my files as far as referencing. Maybe I'm missing something?
//
// hw1_sets.cpp
//
//
#include <iostream>
#include <vector>
#include "hw1.h"
using namespace std;
void set_function::assign() //Assign function
{
cin >> set_function::sets;
cout << set_function::sets << endl;
int i;
if(sets == "R") //if user inputs R
{
for(i=0; i<13; i++) //for loop inputting number into R set
{
cin >> R[i];
// return R[i];
}
}
else if (sets == "S") //if user inputs S
{
for(i=0; i<13; i++) //for loop inputting number into S set
{
cin >> S[i];
// return S[i];
}
}
else if (sets == "T") //if user inputs T
{
for(i=0; i<13; i++) //for loop inputting number into T set
{
cin >> T[i];
// return T[i];
}
}
else
{
cout << "This set does not exist! Try again!" << endl;
}
cout << " set complete" << endl;
};
void set_function::clear() //Clear function
{
//find set
/*cin >> set_function::set;
cout << set_function::set << endl;
int i;
if(set == set_function::R)
{
for(i=0; i<13; i++)
{
//clear R values
}
}
else if (set == set_function.S)
{
for(i=0; i<13; i++)
{
//clear S values
}
}
else if (set == T)
{
for(i=0; i<13; i++)
{
//clear T values
}
}
//remove all values*/
}
void set_function::unionn() //Union function
{
//for loop from 0 to 12 (through all elements)
//if set1[x] or set2[x] = 1
//solution[x]=1
//else
//solution[x]=0
}
void set_function::intersection() //Intersection function
{
//for loop from 0 to 12 (through all elements)
//if set1[x] == set2[x]
//solution[x]=set1[x]
//else
//solution[x]=0
}
void set_function::difference() //difference function
{
//for loop from 0 to 12 (through all elements)
//set1[x]-set2[x]=solution[x]
}
/*printing the set doesn't work*/
void set_function::print() //print function
{
/*string setname;
cin >> setname;
if (setname = "R")
{
for(int i = 0; i<13; i++)
{
cout<< R[i] << "-";
}
cout << endl;
}
else if (setname = "S")
{
for(int i = 0; i<13; i++)
{
cout<< S[i] << "-";
}
cout << endl;
}
else if (setname = "T")
{
for(int i = 0; i<13; i++)
{
cout<< T[i] << "-";
}
cout << endl;
}
//else if lastdigit
//end of command or newline*/
}
//exit
//
// hw1.cpp
//
//
//
//
#include "hw1.h"
#include <iostream>
using namespace std;
int main()
{
string function;
set_function sets(27);
while(1)
{
cout << "sets> ";
cin >> function;
if(function=="assign")
{
sets->assign();
}
else if(function=="clear")
{
sets->clear();
}
else if(function=="union")
{
sets->unionn();
}
else if(function=="intersection")
{
sets->intersection();
}
else if(function=="difference")
{
sets->difference();
}
else if(function=="print")
{
sets->print();
}
else if(function=="quit")
{
// sets->quit();
return 0;
}
else
{
cout<<"error"<<endl;
}
}
}
//
// hw1.h
//
//
//
//
#include <iostream>
using namespace std;
class set_function
{
private:
bool R[13];
bool S[13];
bool T[13];
public:
string sets;
int values[13];
/*void r()
{
R.resize(13);
}
void s()
{
S.resize(13);
}
void t()
{
T.resize(13);
}*/
set_function(int a){}
void assign();
void clear();
void unionn();
void intersection();
void difference();
void print();
// void quit();
};
edit (10/3/13 #12:50p): I changed what was commented on and now I get this problem:
hw1.cpp: In function ‘int main()’:
hw1.cpp:28: error: base operand of ‘->’ has non-pointer type ‘set_function’
hw1.cpp:32: error: base operand of ‘->’ has non-pointer type ‘set_function’
hw1.cpp:36: error: base operand of ‘->’ has non-pointer type ‘set_function’
hw1.cpp:40: error: base operand of ‘->’ has non-pointer type ‘set_function’
hw1.cpp:44: error: base operand of ‘->’ has non-pointer type ‘set_function’
hw1.cpp:48: error: base operand of ‘->’ has non-pointer type ‘set_function’
edit (10/3/13 #1:23p): Fixed. changed the following:
set_function *sets = new set_function(27)
to
set_function *sets;
sets = new set_function(27);
compiles correctly now. Thanks!
That's not a compiler error, it's a linker error. You're getting it because you declared a constructor for your set_function class but didn't ever define it.
So you declare set_function::set_function(int a) in hw1.h. Then main.cpp is correctly compiled as the call to the constructor of set_function is correct as found declared in the header file hw1.h.
But that function is not implemented anywhere, linking occurs and the call is not resolved.
You should implement it right in the header file or in hw1.cpp file.
Related
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Using G++ to compile multiple .cpp and .h files
(13 answers)
Closed last year.
I've got this file where it seems to be an undefined reference but I don't know why, everything it seems correct to me. Someone can help me?
This is the error:
g++ -c driver.cpp -std=c++11 -pedantic -Wall
g++ -o driver driver.o
/usr/bin/ld: driver.o: in function `main':
driver.cpp:(.text+0x23): undefined reference to `TicTacToe::TicTacToe()'
/usr/bin/ld: driver.cpp:(.text+0x2f): undefined reference to `TicTacToe::makeMove()'
collect2: error: ld returned 1 exit status
make: *** [makefile:2: driver] Error 1
And these are the files I'm using:
The driver program:
// driver.cpp: use of TicTacToe class
#include "TicTacToe.h" // include definition of class TicTacToe
int main() {
TicTacToe g; // creates object g of class TicTacToe
g.makeMove(); // invokes function makeMove
}
This is the class:
// TicTacToe.h
#ifndef TICTACTOE_H
#define TICTACTOE_H
#include <array>
class TicTacToe {
private:
enum Status {WIN, DRAW, CONTINUE}; // enumeration constants
std::array<std::array<int, 3>, 3> board;
public:
TicTacToe(); // default constructor
void makeMove(); // make move
void printBoard() const; // print board
bool validMove(int, int) const; // validate move
bool xoMove(int); // x o move
Status gameStatus() const; // game status
};
#endif
These are the class function members:
// TicTacToe.cpp
// Member-function defnitions for class TicTacToe.
#include <iostream>
#include <iomanip>
#include "TicTacToe.h" // include definition of class TicTacToe
using std::cout;
using std::cin;
using std::setw;
TicTacToe::TicTacToe() {
for (int j{0}; j < 3; ++j) { // initialize board
for (int k{0}; k < 3; ++k) {
board[j][k] = ' ';
}
}
}
void TicTacToe::makeMove() {
printBoard();
while (true) {
if (xoMove('X')) {
break;
}
else if (xoMove('O')) {
break;
}
}
}
void TicTacToe::printBoard() const {
cout << " 0 1 2\n\n";
for (int r{0}; r < 3; ++r) {
cout << r;
for (int c = 0; c < 3; ++r) {
cout << setw(3) << static_cast< char > (board[r][c]);
if (c != 2) {
cout << " |";
}
}
if (r != 2) {
cout << "\n ____|____|____\n | | \n";
}
}
cout << "\n\n";
}
bool TicTacToe::xoMove(int symbol) {
int x;
int y;
do {
cout << "Player " << static_cast<char>(symbol) << " enter move: ";
cin >> x >> y;
cout << '\n';
} while (!validMove(x, y));
board[x][y] = symbol;
printBoard();
Status xoStatus = gameStatus();
if (xoStatus == WIN) {
cout << "Player " << static_cast<char>(symbol) << " wins!\n";
return true;
}
else if (xoStatus == DRAW) {
cout << "Game is draw.\n";
return true;
}
else { // CONTINUE
return false;
}
}
bool TicTacToe::validMove(int r, int c) const {
return r >= 0 && r < 3 && c >= 0 && c < 3 && board[r][c] == ' ';
}
// must specify that type Status is part of the TicTacToe class.
TicTacToe::Status TicTacToe::gameStatus() const {
// check for a win on diagonals
if (board[0][0] != ' ' && board[0][0] == board[1][1] && board[0][0] == board[2][2]) {
return WIN;
}
else if (board[2][0] != ' ' && board[2][0] == board[1][1] && board[2][0] == board[0][2]) {
return WIN;
}
// check for win in rows
for (int a{0}; a < 3; ++a) {
if (board[a][0] != ' ' && board[a][0] == board[a][1] && board[a][0] == board[a][2]) {
return WIN;
}
}
// check for win in columns
for (int a{0}; a < 3; ++a) {
if (board[0][a] != ' ' && board[0][a] == board[1][a] && board[0][a] == board[2][a]) {
return WIN;
}
}
// check for a completed game
for (int r{0}; r < 3; ++r) {
for (int c{0}; c < 3; ++c) {
if (board[r][c] == ' ') {
return CONTINUE; // game is not finished
}
}
}
return DRAW; // game is a draw
}
It's probably something stupid but I don't know what I have to look for.
step by step:
g++ -c driver.cpp TicTacToe.cpp -std=c++11 -pedantic -Wall
g++ -o driver driver.o TicTacToe.o
./driver
Our school submissions are all through matrix using valgrind, which checks the output line by line. However, when submitting, I'm getting "Memory Error Detected".
Compile result:
Success! No errors or warnings...
Execution:
Script started, file is student_output.txt
Script started, file is student_output.txt
==110143== Memcheck, a memory error detector
==110143== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==110143== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==110143== Command: ms
==110143==
Loading Data
Library Application:
When inputing data:
Publication Title: e
==111103== Conditional jump or move depends on uninitialised value(s)
==111103== at 0x404318: sdds::LibApp::search(int, char) (LibApp.cpp:145)
==111103== by 0x404ABC: sdds::LibApp::removePublication() (LibApp.cpp:329)
==111103== by 0x404DC1: sdds::LibApp::run() (LibApp.cpp:415)
==111103== by 0x404F6F: runLibApp(char const*) (LibAppMain_prof.cpp:9)
==111103== by 0x405084: main (LibAppMain_prof.cpp:20)
==111103==
Other information
I also get error while adding a publication, (using the newPublication() function), which in the same file below.
==140314== Use of uninitialised value of size 8
==140314== at 0x404926: sdds::LibApp::newPublication() (LibApp.cpp:282)
==140314== by 0x404DAA: sdds::LibApp::run() (LibApp.cpp:411)
==140314== by 0x404F6F: runLibApp(char const*) (LibAppMain_prof.cpp:9)
==140314== by 0x405084: main (LibAppMain_prof.cpp:20)
==140314==
==140314== Use of uninitialised value of size 8
==140314== at 0x40493F: sdds::LibApp::newPublication() (LibApp.cpp:284)
==140314== by 0x404DAA: sdds::LibApp::run() (LibApp.cpp:411)
==140314== by 0x404F6F: runLibApp(char const*) (LibAppMain_prof.cpp:9)
==140314== by 0x405084: main (LibAppMain_prof.cpp:20)
==140314==
The file is posted below.
LibApp.cpp
#define _CRT_SECURE_NO_WARNINGS
#include <fstream>
#include <iostream>
#include <fstream>
#include <cstring>
#include <iomanip>
#include "LibApp.h"
#include "Book.h"
#include "PublicationSelector.h"
namespace sdds {
int NOLP=0;
int LLRN=0;
bool LibApp::confirm(const char* message)
{
Menu conf(message);
conf<<"Yes";
int t_return = conf.run();
if(t_return) return true;
return false;
}
LibApp::LibApp(const char filename[256])
{
m_mainMenu << "Add New Publication"
<< "Remove Publication"
<< "Checkout publication from library"
<<"Return publication to library";
m_exitMenu << "Save changes and exit" << "Cancel and go back to the main menu";
strcpy(m_filename, filename);
m_publicationMenu << "Book" << "Publication" ;
load();
}
LibApp::~LibApp()
{
for (int i = 0; i< NOLP ; i++) {
delete PPA[i];
}
}
void LibApp::load(){
std::cout<<"Loading Data\n";
std::ifstream infile(m_filename);
char type{};
for (int i = 0; infile ; i++) {
infile >> type;
infile.ignore();
if (infile) {
if (type == 'P')
PPA[i] = new Publication;
else if (type == 'B')
PPA[i] = new Book;
else std::cout<<"no data\n";
if (PPA[i] && i < SDDS_LIBRARY_CAPACITY ) {
infile >> *PPA[i];
LLRN=PPA[i]->getRef();
NOLP++;
}
}
}
}
void LibApp::save(){
std::cout<<"Saving Data\n";
std::ofstream outfile(m_filename);
for (int i = 0; i < NOLP; i++) {
if (PPA[i]->getRef()!=0) {
outfile << *PPA[i] << std::endl;
}
}
}
void prnPub(Publication* p[], int size, int ref) {
int i;
for (i = 0; i < size; i++) {
if (ref == p[i]->getRef()) {
std::cout << *p[i] << std::endl;
i = size;
}
}
}
int LibApp::search(int option,char type){
PublicationSelector ps("Select one of the following found matches:", 15);
std::cout<<"Publication Title: ";
char title[256];
std::cin.getline(title,256);
if(option==1)
{
for (int i = 0; i< NOLP; i++) {
if (strstr(*PPA[i],title) && PPA[i]->getRef()!=0 && type==PPA[i]->type())
ps << PPA[i];
}
}
else if(option==2)
{
for (int i = 0; i< NOLP; i++) {
if (strstr(*PPA[i],title) && !PPA[i]->onLoan() && PPA[i]->getRef()!=0 && type==PPA[i]->type())
ps << PPA[i];
}
}
else if(option==3)
{
for (int i = 0; i< NOLP; i++) {
if (strstr(*PPA[i],title) && PPA[i]->onLoan() && PPA[i]->getRef()!=0 && type==PPA[i]->type())
ps << PPA[i];
}
}
int ref = 0;
if (ps) {
ps.sort();
ref = ps.run();
if (ref) {
prnPub(PPA, NOLP , ref);
}
else {
std::cout << "Aborted!\n";
}
}
else {
std::cout << "No matches to found!" << std::endl;
}
return ref;
}
void LibApp::returnPub()
{
std::cout<<"Return publication to the library\n";
int i=m_publicationMenu.run();
char type;
if(i==1) type='B';
else type='P';
int ref=search(3,type);
if(ref!=0 && confirm("Returning publication?"))
{
Date date=getPub(ref)->checkoutDate();
Date today;
int days=today-date;
days-=15;
if(days>0)
{
std::cout << std::fixed;
std::cout << std::setprecision(2);
std::cout<<"Please pay $"<<float(days)*(0.5)<<" penalty for being "<<days<<" days late!\n";
}
getPub(ref)->set(0);
std::cout<<"Publication returned\n";
m_changed=true;
}
}
void LibApp::newPublication()
{
if( NOLP >= SDDS_LIBRARY_CAPACITY )
{
std::cout<<"Library is at its maximum capacity!\n";
return;
}
std::cout<<"Adding new publication to library\n";
int i=m_publicationMenu.run();
Publication *p=nullptr;
if(i==0)
{ std::cout<<"Aborted!\n";
return;
}
else if(i==1)
{
p = new Book;
std::cin >> *p;
}
else if( i==2 )
{
p = new Publication;
std::cin >> *p;
}
if(std::cin.fail())
{
std::cout<<"\nAborted!\n";
exit(0);
}
if(confirm("Add this publication to library?"))
{
m_changed = true;
PPA[NOLP]=p;
LLRN=PPA[NOLP]->getRef();
NOLP++;
std::cout<<"Publication added\n";
}
if( !*p )
{
std::cout<<"Failed to add publication!\n";
delete p;
}
}
Publication* LibApp::getPub(int libRef)
{
for(int i=0;i<NOLP;i++)
{
if(libRef==PPA[i]->getRef()) return PPA[i];
}
return nullptr;
}
void LibApp::removePublication()
{
//std::cout<<;
std::cout<<"Removing publication from the library\n";
int i=m_publicationMenu.run();
char type;
if(i==1) type='B';
else
{
type='P';
}
int ref=search(1,type);
if(ref!=0 && confirm("Remove this publication from the library?"))
{
m_changed = true;
getPub(ref)->setRef(0);
std::cout<<"Publication removed\n";
}
}
void LibApp::checkOutPub()
{
std::cout<<"Checkout publication from the library\n";
int i=m_publicationMenu.run();
char type;
if(i==1) type='B';
else type='P';
int ref=search(2,type);
if(ref!=0 && confirm("Check out publication?"))
{
m_changed = true;
int mn;
std::cout << "Enter Membership Number: ";
while (1)
{
std::cin>>mn;
if(mn > 9999 && mn <= 99999 ) break;
std::cout<<"Invalid membership number, try again: ";
}
getPub(ref)->set(mn);
std::cout<<"Publication checked out\n";
}
}
LibApp::LibApp()
{
m_mainMenu << "Add New Publication"
<< "Remove Publication"
<< "Checkout publication from library"
<<"Return publication to library";
m_exitMenu << "Save changes and exit" << "Cancel and go back to the main menu";
load();
}
void LibApp::run()
{
while(1)
{
int option = m_mainMenu.run();
if( option == 1 )
{
newPublication();
}
else if( option == 2 )
{
removePublication();
}
else if( option == 3 )
{
checkOutPub();
}
else if( option == 4 )
{
returnPub();
}
else if( option == 0 )
{
if(m_changed)
{
int opn = m_exitMenu.run();
if( opn == 1 )
{
save();
break;
}
else if( opn == 2 )
{
;
}
else if( opn == 0)
{
if(confirm("This will discard all the changes are you sure?"))
break;
}
}
else break;
}
std::cout<<std::endl;
}
std::cout<<std::endl;
std::cout<<"-------------------------------------------\n";
std::cout<<"Thanks for using Seneca Library Application\n";
}
}
Please help me with this. My submission is today idk what the issues are.
Like the error message says:
Conditional jump or move depends on uninitialised value(s)
==111103== at 0x404318: sdds::LibApp::search(int, char) (LibApp.cpp:145)
There is an if-statement (or something logically equivalent to an if-statement) at line 145 of LibApp.cpp that is basing its decision on which path to take on a variable that was never initialized to any value; as such, the behavior of that if-test is undefined (ie if could go either way depending on what arbitrary data happens to be present at that variable’s memory location at the time).
So you’ll need to look at the variable(s) present in the if-test at line 145 to figure out which ones aren’t being set beforehand, and then fix the error by making sure they do get set first.
If necessary, you can add temporary if-tests just to provoke valgrind into giving you more results:
if (some_suspect_var != 0) fprintf(stderr, “Yea\n”);
else fprintf(stderr, “Nay\n”);
… then if you get a valgrind error on that if-line, you know that some_suspect_var is uninitialized at that point.
I wrote a working, linked-queue that is templated on it's datatype, however the user may be inputing data in one of a few different types. How can I select which datatype will be used at run-time?
It works fine if I use each type individually; I just need every possibility covered without changing code or re-writing overloaded functions for every data type.
Below I've provided the relevant pieces of my code. As I said, no problems with my class member functions.
I already have tried a switch statement that creates x type version of the queue, but that cannot work as later possibilities within the switch "contradict" with other queue data types. I am currently trying if/else if statements, with no errors other than when I try to use the input of x type, it says it is undefined.
// From Source.cpp
#include <iostream>
#include <string>
using namespace std;
#include "LQueue.h"
int mainMenu();
int main()
{
int value;
bool stop = false;
Queue<int> *theQueue;
int choice = mainMenu();
if (choice == 1) {
Queue<int> theQueue;
int dataType;
}
else if (choice == 2) {
Queue<double> theQueue;
double dataType;
}
else if (choice == 3) {
Queue<string> theQueue;
string dataType;
}
else if (choice == 4) {
Queue<char> theQueue;
char dataType;
}
cout << "\n\nHow many items would you like to initially"
<< " populate the queue with? ";
int howMany;
cin >> howMany;
for (int i = 0; i < howMany; i++)
{
cin >> dataType;
theQueue.enqueue(dataType)
}
theQueue.display(cout);
theQueue.dequeue();
theQueue.display(cout);
return 0;
}
int mainMenu()
{
int choice;
cout << "What type of data will you be storing in the queue?\n"
<< "1. integers\n2. decimal numbers\n3. words\n4. chars\n\n";
cin >> choice;
if (choice > 0 && choice < 5)
return choice;
cout << "\n\nInvalid choice\n\n";
mainMenu();
}
// Guess I'll include shown functions from the Queue class file below
//--- Definition of enqueue()
template <typename QueueElement>
void Queue<QueueElement>::enqueue(const QueueElement & value)
{
if (empty())
{
myFront = myBack = new Node(value);
}
else
{
myBack->next = new Node(value);
myBack = myBack->next;
}
}
//--- Definition of dequeue()
template <typename QueueElement>
void Queue<QueueElement>::dequeue()
{
if (empty() == false)
{
Queue::NodePointer oldFront = myFront;
myFront = myFront->next;
delete oldFront;
}
}
//--- Definition of display()
template <typename QueueElement>
void Queue<QueueElement>::display(ostream & out) const
{
Queue::NodePointer ptr;
for (ptr = myFront; ptr != 0; ptr = ptr->next)
out << ptr->data << " ";
out << endl;
}
//--- Definition of front()
template <typename QueueElement>
QueueElement Queue<QueueElement>::front() const
{
if (!empty())
return (myFront->data);
else
{
cerr << "*** Queue is empty "
" -- returning garbage ***\n";
QueueElement * temp = new(QueueElement);
QueueElement garbage = *temp; // "Garbage" value
delete temp;
return garbage;
}
}
Compiler (visual studio 2017) is showing identifier "dataType" is undefined within the following loop:
```c++
for (int i = 0; i < howMany; i++)
{
cin >> dataType;
theQueue.enqueue(dataType);
}
2 errors: E0020 and C2065 on the "cin >> dataType;" line, and also another
C2065 on the next line
Maybe there is a more efficient way overall of doing this? I am open to any and all suggestions, thank you!
The problem (a problem) is that when you write
if (choice == 1) {
Queue<int> theQueue;
int dataType;
}
else if (choice == 2) {
Queue<double> theQueue;
double dataType;
}
else if (choice == 3) {
Queue<string> theQueue;
string dataType;
}
else if (choice == 4) {
Queue<char> theQueue;
char dataType;
}
you define four different theQueue and four different dataType variables that are, each one, valid only inside the corresponding body of the corresponding if.
So, when you write
for (int i = 0; i < howMany; i++)
{
cin >> dataType;
theQueue.enqueue(dataType)
}
theQueue.display(cout);
theQueue.dequeue();
theQueue.display(cout);
there are no more dataType and theQueue available (all of they are out of scope).
I suggest something as follows
if (choice == 1) {
foo<int>();
}
else if (choice == 2) {
foo<double>();
}
else if (choice == 3) {
foo<std::string>();
}
else if (choice == 4) {
foo<char>();
}
where foo() is a template function almost like this (caution: code not tested)
template <typename T>
void foo ()
{
Queue<T> theQueue;
T dataType;
std::cout << "\n\nHow many items would you like to initially"
<< " populate the queue with? ";
int howMany;
std::cin >> howMany;
for (int i = 0; i < howMany; i++)
{
std::cin >> dataType;
theQueue.enqueue(dataType)
}
theQueue.display(cout);
theQueue.dequeue();
theQueue.display(cout);
}
Write a templated member function that does what you want:
template<class DataType>
void processInput(int howMany) {
DataType value;
for (int i = 0; i < howMany; i++)
{
cin >> value;
theQueue.enqueue(value);
}
theQueue.display(cout);
theQueue.dequeue();
theQueue.display(cout);
}
Method 1 - switch statement
We can then use a switch statement to select between them in main:
int main()
{
int choice = mainMenu();
cout << "\n\nHow many items would you like to initially "
"populate the queue with? ";
int howMany;
cin >> howMany;
switch(choice) {
case 1:
processInput<int>(howMany);
break;
case 2:
processInput<double>(howMany);
break;
case 3:
processInput<string>(howMany);
break;
case 4:
processInput<char>(howMany);
break;
}
}
Method 2 - array of methods
We can use an array to do a lookup!
using func_t = void(*)(int);
int main() {
std::vector<func_t> options = {
processInput<int>,
processInput<double>,
processInput<string>,
processInput<char>
};
int choice = mainMenu();
func_t selectedOption = options[choice - 1];
cout << "\n\nHow many items would you like to initially "
"populate the queue with? ";
int howMany;
cin >> howMany;
selectedOption(howMany);
}
When I use the object function set_and_make_variable I send it a name and value which both work correctly. However then when I go to use show current_variables it acts like I never set the values for both integers, and integers_names. I thought you could modify the variables arrays from the functions associated with the class without references or pointers.
Am I not correct?
void reset_name(string *variable_names)
{
for (int i = 0; i < 100; i++)
{
variable_names[i] = "";
}
}
void reset_int_value(int *variable_value)
{
for (int i = 0; i < 100; i++)
{
variable_value[i] = 0;
}
}
int find_next(string variable_names[100])
{
for (int i = 0; i < 100; i++)
{
if (variable_names[i] == "")
{
return i;
}
}
}
//*****************************************************************
class variables_integers
{
public:
string integer_names[100];
int integers[100];
variables_integers(void);
void set_and_make_variable(string, int);
void show_current_variables(void);
};
variables_integers::variables_integers(void)
{
reset_int_value(integers);
reset_name(integer_names);
}
void variables_integers::show_current_variables(void)
{
cout << "INTEGERS:" << endl;
for (int i = 0; i < (find_next(integer_names)); i++)
{
cout << integer_names[i] << " = " << integers[i] << endl;
}
}
void variables_integers::set_and_make_variable(string name, int value)
{
cout << name << " " << value << endl;
cout << find_next(integer_names) << endl;
integers[find_next(integer_names)] = value;
integer_names[find_next(integer_names)] = name;
}
//*** added code ******
bool operations_and_declerations(string parsed_input[3000], variables variable)
{
if (parsed_input[0] == "int")
{
if (parsed_input[2] == "=")
{
variable.integers.set_and_make_variable(parsed_input[1], atoi(parsed_input[3].c_str()));
}
return true;
}
else if (parsed_input[0] == "string")
{
return true;
}
//else if (parsed_input[0] ==)
else
{
return false;
}
}
In operations_and_declerations(), you sent your variables parameter by value. Hence, the function created a local copy, and only modified that local copy.
You can fix the problem by sending it the parameter by reference. Just modify the function name to:
bool operations_and_declerations(string parsed_input[3000], variables & variable)
So I am trying to make a pretty basic TicTacToe in C++, and while I have no apparent syntax errors, I am having a lot of Debug errors of : "Unhandled exception at 0x0100142D in Cobra.exe: 0xC0000005: Access violation reading location 0xCCCCC359"
I feel like it is an obvious Error that I am just not processing but it;s definitely starting to grate my nerves. I'll label where the access error is... Right now it;s in my checkwin method but I feel like there is definitely more than one..
In my header I use a private char** board and a private int player.
#include "TicTacToe.h"
#include <iostream>
using namespace std;
int main()
{
int rowChosen,
colChosen;
TicTacToe newGame;
while(newGame.checkWin()==' ' && !newGame.fullBoard())
{
newGame.displayBoard();
do
{
cout << "Player " << newGame.getPlayer() << " choose a row and column.";
cin >> rowChosen >> colChosen;
newGame.setGame(rowChosen,colChosen);
}while(newGame.setGame(rowChosen,colChosen)==false);
newGame.makeMove(rowChosen, colChosen, newGame.getPlayer());
newGame.switchPlayer();
}
newGame.displayBoard();
if(newGame.checkWin()!=' ')
cout << "Player " << newGame.returnWinner() << " wins!";
else if(newGame.fullBoard()==true)
cout << "Cat's Game: This is a Draw!";
return 0;
}
TicTacToe::TicTacToe()
{
player = 1;
char blank = ' ';
for(int row=0;row<3;row++)
for(int col=0;col<3;col++)
board[row][col] = ' ';
}
void TicTacToe::setPlayer(int play)
{
player = play;
}
int TicTacToe::getPlayer()
{
return player;
}
void TicTacToe::switchPlayer()
{
if (player==1)
player++;
else
player--;
}
bool TicTacToe::setGame(int row, int col) //input validation
{
if (row >= 3 || row < 0)
return false;
if (col >= 3 || col < 0)
return false;
if (board[row][col] != ' ')
return false;
return true;
}
char TicTacToe::getBoard(int row, int col)
{
return board[row][col];
}
bool TicTacToe::fullBoard()
{
bool full = true;
for(int row=0;row<3;row++)
for(int col=0;col<3;col++)
{
if(board[row][col]==' ')
{
full=false;
break;
}
}
return full;
}
void TicTacToe::makeMove(int r, int c, int player)
{
char ch;
if (player==1)
ch = 'X';
else
ch = 'O';
board[r][c] = ch;
}
char TicTacToe::checkWin()
{
char b = ' ';
for(int i=0; i<3; i++) //horizontal
{
if((board[i][1]==board[i][0]) && (board[i][1]==board[i][2])) //THIS IS ERROR
{
b=board[i][1];
}
}
for(int j=0; j<3; j++) //vertical
{
if( (board[1][j]==board[0][j]) && (board[1][j]==board[2][j]) )
b=board[1][j];
}
if((board[0][0]==board[1][1] && board[1][1]==board[2][2]) ||
(board[2][0]==board[1][1] && board[1][1]==board[0][2]))
b= board[1][1];
return b;
}
void TicTacToe::displayBoard()
{
for(int row=0;row<3;row++)
{
cout << "|-----|";
for(int col=0;col<3;col++)
{
if(board[row][col]==' ')
cout << "| ";
else
cout << "|" << board [row][col];
}
cout << "|" << endl;
cout << "|-----|";
}
}
int TicTacToe::returnWinner()
{
int winner = 0;
if(checkWin()=='X')
winner = 1;
else if(checkWin()=='O')
winner = 2;
return winner;
}
This is my header TicTacToe.h
class TicTacToe
{
private:
char board[3][3]; //there we go
int player;
public:
TicTacToe();
void setPlayer(int);
int getPlayer();
void switchPlayer();
bool setGame(int,int);
char getBoard(int,int);
bool fullBoard();
void makeMove(int,int,int);
char checkWin();
void displayBoard();
int returnWinner();
};
Assuming you've included all the code, you're missing something essential: the declaration of the class TicTacToe. Of course, there's a TicTacToe.h, so it could be (probably is) hiding in there. That would help.
That all said, I think Mat has it right -- you declare a local named board inside the ctor and initialize it. But that goes out of scope as soon as the ctor is finished, which means all that initialization disappears into the aether.. Assuming you define board in your class, then simply removing that char declaration might be all you need.
Now, here's general advice: if you get an access violation exception, it usually means that you have made a mistake about the scope of something you're referring to. Since the exception happens at a point where you're using board, the slice of the program containing the identified board is the place to look.