Random number generator sometimes fails to start in Eclipse - eclipse

I have written some code that produces an object which returns a unique random number when queried. However, every once in about 6 or 7 runs the program fails to start, and there seems to be no apparent reason for this. Also, my memory seems to drop over time (using a vector in the class). Any ideas?
/*
* Urn.h
*
* Created on: Jan 17, 2014
* Author: edwinrietmeijer
*/
#ifndef URN_H_
#define URN_H_
#include <cstdlib>
#include <vector>
#include <iostream>
class Urn {
private:
int highRand;
int loRand;
int numsTotal;
int numsLeft;
std::vector<int>numsAvailable;
public:
Urn();
int getRand();
int getSize();
void reset();
virtual ~Urn();
};
#endif /* URN_H_ */
/*
* Urn.cpp
*
* Created on: Jan 17, 2014
* Author: edwinrietmeijer
*/
#include "Urn.h"
using namespace std;
Urn::Urn() : highRand( 9 ), loRand( 0 ) {
vector<int>::iterator pos;
int newRandom;
numsTotal = highRand - loRand;
bool newRandomExists = false;
while ( numsAvailable.size() < numsTotal + 1 )
{
do {
newRandomExists = false;
newRandom = ( rand() % ( numsTotal + 1 ) ) + loRand;
for ( pos = numsAvailable.begin(); pos != numsAvailable.end(); pos++ ) {
// cout << *pos << " ";
if ( *pos == newRandom ) {
newRandomExists = true;
}
}
// cout << " Random -> " << newRandom << " " << newRandomExists << endl;
} while ( newRandomExists == true );
newRandomExists = false;
numsAvailable.push_back( newRandom );
}
cout << endl;
// List the list
for (pos = numsAvailable.begin(); pos != numsAvailable.end(); pos++ ) {
// cout << *pos << " ";
}
// cout << endl;
// TODO Auto-generated constructor stub
}
int Urn::getRand() {
vector<int>::iterator pos = numsAvailable.begin();
int numToReturn = numsAvailable.back( );
numsAvailable.erase( pos );
return numToReturn;
}
int Urn::getSize() {
return numsAvailable.size();
}
void Urn::reset() {
}
Urn::~Urn() {
// TODO Auto-generated destructor stub
}
//============================================================================
// Name : UniqueRand.cpp
// Author : Edwin Rietmeijer
// Version :
// Copyright : This code is owned by Edwin Rietmeijer as of 2014
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
#include <string>
#include "Urn.h"
using namespace std;
int main() {
cout << "Seeding..." << endl;
srand( time( NULL ) );
cout << "Getting object..." << endl;
Urn * urnObject = new Urn;
cout << urnObject -> getRand();
return 0;
}

Related

NS3 scheduling simulation. Custom client/server application using ARQ on application layer. Problem in NS_LOG_FUNCTION results

I"m new in ns3 guys so please take it easy with me, this is a very basic question I hope someone can answer me.
I'm working on a custom application using UDP sockets in ns3. I wrote a simple two functions, one is sendPacket(Ptr packet) and the second is HandleReadOne() to output the content of the packet received. By creating 2 node and setup 1 of them as a source node and the second as a destination. when I send 1000 packet all the packets are sent by sendPacket function but in the output using NS_LOG_INFO in handleReadOne() function, I get only 3 packets in output!! Please guys HELP ((
the main class and the class where the two function are wrote is follow:
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/applications-module.h"
#include "ns3/internet-module.h"
#include "source-application.h"
#include "sink-application.h"
#include "nack-data-tag.h"
#include "packet-data-tag.h"
#include "netDevice-setup.h"
#include "ns3/mobility-module.h"
#define PACKET_SIZE 1000;
using namespace ns3;
int main (int argc, char *argv[])
{
CommandLine cmd;
uint32_t nNodes = 2;
double simTime = 60; //4 seconds
double interval = 0.5;
bool enablePcap = false;
cmd.AddValue ("t","Simulation Time", simTime);
cmd.AddValue ("i", "Broadcast interval in seconds", interval);
cmd.AddValue ("n", "Number of nodes", nNodes);
cmd.AddValue ("pcap", "Enable PCAP", enablePcap);
cmd.Parse (argc, argv);
NodeContainer nodes;
nodes.Create(nNodes);
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::ConstantVelocityMobilityModel");
mobility.Install(nodes);
for (uint32_t i=0 ; i<nodes.GetN(); i++)
{
Ptr<ConstantVelocityMobilityModel> cvmm = DynamicCast<ConstantVelocityMobilityModel> (nodes.Get(i)->GetObject<MobilityModel>());
cvmm->SetPosition ( Vector (20+i*5, 20+(i%2)*5, 0));
cvmm->SetVelocity ( Vector (10+((i+1)%2)*5,0,0) );
}
NetDeviceSetup setup;
NetDeviceContainer devices = setup.ConfigureDevices (nodes);
InternetStackHelper stack;
stack.Install (nodes);
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer ifaces;
ifaces = address.Assign (devices);
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
Packet::EnablePrinting ();
Ptr <SourceApplication> appSink = CreateObject <SourceApplication> ();
Ptr <SourceApplication> appSource = CreateObject <SourceApplication> ();
appSink->SetStartTime (Seconds(1));
appSink->SetStopTime (Seconds (simTime));
Ipv4Address dest_ip ("10.1.1.2");
Ipv4Address my_ip("10.1.1.1");
appSink->SetDestinationAddr (dest_ip);
appSink->SetMyAddr (my_ip);
appSource->SetStartTime (Seconds(2));
appSource->SetStopTime (Seconds (simTime));
Ipv4Address dest_ip2 ("10.1.1.1");
appSource->SetDestinationAddr (dest_ip2);
Ipv4Address my_addr2 ("10.1.1.2");
appSource->SetMyAddr (my_addr2);
nodes.Get(0)->AddApplication (appSink);
nodes.Get(1)->AddApplication (appSource);
LogComponentEnable ("SourceApplication", LOG_LEVEL_ALL);
Simulator::Stop (Seconds (simTime));
Simulator::Run ();
Simulator::Destroy ();
}
===================SourceApplication class==================
#include "ns3/log.h"
#include "source-application.h"
#include "ns3/udp-socket.h"
#include "ns3/simulator.h"
#include "ns3/csma-net-device.h"
#include "ns3/ethernet-header.h"
#include "ns3/arp-header.h"
#include "ns3/ipv4-header.h"
#include "ns3/udp-header.h"
#include "packet-data-tag.h"
#define PURPLE_CODE "\033[95m"
#define CYAN_CODE "\033[96m"
#define TEAL_CODE "\033[36m"
#define BLUE_CODE "\033[94m"
#define GREEN_CODE "\033[32m"
#define YELLOW_CODE "\033[33m"
#define LIGHT_YELLOW_CODE "\033[93m"
#define RED_CODE "\033[91m"
#define BOLD_CODE "\033[1m"
#define END_CODE "\033[0m"
namespace ns3
{
NS_LOG_COMPONENT_DEFINE("SourceApplication");
NS_OBJECT_ENSURE_REGISTERED(SourceApplication);
TypeId
SourceApplication::GetTypeId()
{
static TypeId tid = TypeId("ns3::SourceApplication")
.AddConstructor<SourceApplication>()
.SetParent<Application>();
return tid;
}
TypeId
SourceApplication::GetInstanceTypeId() const
{
return SourceApplication::GetTypeId();
}
//Constructor
SourceApplication::SourceApplication()
{
m_port1 = 7777;
m_port2 = 9999;
m_packet_size = 1000;
m_number_of_packets_to_send = 50;
}
//Destructor
SourceApplication::~SourceApplication()
{
}
void SourceApplication::SetupReceiveSocket(Ptr<Socket> socket, Ipv4Address myAddr, uint16_t port)
{
InetSocketAddress local = InetSocketAddress(myAddr, port);
if (socket->Bind(local) == -1)
{
NS_FATAL_ERROR("Failed to bind socket");
}
}
void SourceApplication::SetDestinationAddr (Ipv4Address dest_addr){
m_destination_addr = dest_addr;
}
Ipv4Address SourceApplication::GetDestinationAddr (){
return m_destination_addr;
}
void SourceApplication::SetMyAddr (Ipv4Address my_addr){
m_my_addr = my_addr;
}
Ipv4Address SourceApplication::GetMyAddr (){
return m_my_addr;
}
void SourceApplication::StartApplication()
{
Ptr<UniformRandomVariable> rand = CreateObject<UniformRandomVariable> ();
m_random_offset = MicroSeconds (rand->GetValue(2,10));
NS_LOG_FUNCTION("Start application ... " << m_my_addr);
TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
m_recv_socket1 = Socket::CreateSocket(GetNode(), tid);
SetupReceiveSocket(m_recv_socket1, m_my_addr, m_port1);
m_send_socket = Socket::CreateSocket(GetNode(), tid);
//If the application of node source, then sendPacket will be scheduled
if(this->m_my_addr == ("10.1.1.2")){
for(int i = 0; i < 100; i++){
Ptr <Packet> packet = Create <Packet> (m_packet_size);
PacketDataTag tag;
tag.SetSeqNumber (i);
tag.SetTimestamp (Now ());
packet->AddPacketTag (tag);
this->SendPacket (packet);
}
}
m_recv_socket1->SetRecvCallback(MakeCallback(&SourceApplication::HandleReadOne, this));
}
void SourceApplication::HandleReadOne(Ptr<Socket> socket)
{
//NS_LOG_FUNCTION(this << socket);
Ptr<Packet> packet;
Address from;
Address localAddress;
PacketDataTag tag;
while ((packet = socket->RecvFrom(from)))
{
if(packet->PeekPacketTag (tag)){
NS_LOG_INFO(TEAL_CODE << "HandleReadOne: node " << GetNode ()->GetId ()<< " Received " << packet->GetSize() << " bytes"
<< " at time " << Now().GetSeconds ()<< " from " <<InetSocketAddress::ConvertFrom (from).GetIpv4 ()
<< " port " <<InetSocketAddress::ConvertFrom (from).GetPort () << " timestimp "
<< tag.GetTimestamp () << " seq-number: " << tag.GetSeqNumber () << END_CODE);
}else {
NS_LOG_INFO(PURPLE_CODE << "HandleReadOne: node " << GetNode ()->GetId ()<< " Received a Packet of size: " << packet->GetSize()
<< " at time " << Now().GetSeconds() << " from " <<InetSocketAddress::ConvertFrom (from).GetIpv4 ()
<< " port " <<InetSocketAddress::ConvertFrom (from).GetPort ()
<< END_CODE);
}
}
}
void SourceApplication::SendPacket(Ptr<Packet> packet)
{
//NS_LOG_FUNCTION (this << m_my_addr << m_port1 );
m_send_socket->Connect(InetSocketAddress(m_destination_addr, m_port1));
m_send_socket->Send(packet);
//Simulator::Schedule(Seconds (3), &SourceApplication::SendPacket, this, packet); //, dest_ip, 7777);
}
} // namespace ns3

How do I change a pointer variable's value and keep the changes outside of a function without pass-by-reference?

I am doing a project for a class writing C-String-editing functions. 3/5 of the functions I have to write change the size of the char arrays I have to use, and they are being read through an ifstream input. Here is the program:
#include <iostream>
#include <fstream>
using namespace std;
void stringCopy(char *A, char *B);
bool stringCompare(char *A, char *B);
void stringConcatenation(char *A, char *B); //added const to make sure b is never changed
int stringPosition(char *A, char B);
int stringLength(char *A);
//-------------------MY-FUNCTIONS----------------------
int cStringLen(const char*); //finds string length, but doesn't account for null char
void reSize(char*&, int len, int newLen);
void input(char*& A, istream& is);
void printMessage(const char* word1, const char* word2, const char* message);
int main()
{
ifstream ifs{"input.txt"};
ofstream ofs{"output.txt"};
char* word1 = "";
char* word2 = "";
input(word1, ifs);
input(word2, ifs);
printMessage(word1, word2, "stringCopy()");
stringCopy(word1, word2);
printMessage(word1, word2, "after stringCopy()");
cout << endl;
input(word1, ifs);
input(word2, ifs);
printMessage(word1, word2, "stringCompare()");
if(stringCompare(word1, word2))
{
cout << "They match!" << endl;
}
else
{
cout << "They don't match!" << endl;
}
stringCopy(word1, word2);
printMessage(word1, word2, "comparing after stringCopy()");
if(stringCompare(word1, word2))
{
cout << "They match!" << endl;
}
else
{
cout << "They don't match!" << endl;
}
cout << endl;
input(word1, ifs);
input(word2, ifs);
printMessage(word1, word2, "stringConcatenation()");
stringConcatenation(word1, word2);
printMessage(word1, word2, "after stringConcatenation()");
cout << endl;
input(word1, ifs);
input(word2, ifs);
printMessage(word1, word2, "stringPosition()");
cout << "Searching for 'm' in word1..." << endl << "position returned is: " << stringPosition(word1, 'm') << endl;
cout << "Searching for 'n' in word2..." << endl << "position returned is: " << stringPosition(word2, 'n') << endl;
cout << endl;
input(word1, ifs);
cout << "stringLength()" << endl;
cout << "word1: " << word1 << endl;
cout << "The length of word1 is: " << stringLength(word1) << endl;
cout << "after stringLength()" << endl;
cout << "word1: " << word1 << endl;
return 0;
}
void stringCopy(char *A, char *B)
{
///GETTING THE SIZES OF BOTH ARRAYS
int counterA = cStringLen(A) + 1;
int counterB = cStringLen(B) + 1;
///MAKES SURE BOTH ARE THE SAME SIZE BEFORE COPYING
if(counterA < counterB)
{
reSize(A, counterA, counterB);
}
else
{
reSize(A, counterB, counterA);
}
///THE COPY
for(int i = 0; i < counterB; i++) *(A + i) = *(B + i); //each character is copied to A from B
}
bool stringCompare(char *A, char *B)
{
///getting length of one string
int counter = cStringLen(A);
///will move through string until diff char found
for(int i = 0; i < counter + 1; i++)
{
if(*(A + i) != *(B + i))
{
return false;
}
}
return true;
}
void stringConcatenation(char *A, char *B) //added const to make sure b is never changed
{
///getting length of both strings
int counterA = cStringLen(A)+1;
int counterB = cStringLen(B)+1;
///putting the length of both together for new string
const int COUNTERS = counterA + counterB - 1;
///making A the size of both strings - 1
reSize(A, counterA, COUNTERS);
///copying b to the parts of a past the original
for(int i = 0; i < counterB; i++)
{
*(A + (counterA - 1) + i) = *(B + i); //will override the '/0' char of A
}
}
int stringPosition(char *A, char B)
{
int counter = cStringLen(A) + 1;
///searching through string for char
for(int i = 0; i < counter; i++)
{
if(*(A + i) == B)
{
return i; //found!
}
}
///checking if b == '\0' and a '\0' isn't found somewhere before last spot of A
if(B == '\0')
{
return counter;
}
return -1; //not found
}
int stringLength(char *A)
{
int counter = cStringLen(A) + 1;
char* car = new char[counter + 1];
for(int i = 0; i < counter; i++)
{
*(car + 1 + i) = *(A + i);
}
*(car + 0) = counter;
delete[] A;
A = car;
/**
* Will take string as param.
* Shifts all characters to the right by one and store the length of the string in position 0.
- Length doesn't include position 0.
*/
return counter; //temp
}
//-----------------------------------------MY FUNCTIONS---------------------------------------------------------------------------
int cStringLen(const char* A) //finds string length, but doesn't account for null char
{
int counter = 0;
while(*(A + counter) != '\0')
{
counter++;
}
return counter;
}
void reSize(char*& A, int len, int newLen)
{
char* car = new char[newLen];
for(int i = 0; i < newLen; i++)
{
if(i < len)
{
*(car + i) = *(A + i);
}
else if(i >= len && i < newLen)
{
*(car + i) = '\0';
}
}
delete[] A;
A = car;
}
void input(char*& A, istream& is)
{
int wordSize = 0;
int arrSize = 1;
char c = 'o'; //checking char
char* car = new char[arrSize];
while((!(is.eof())) && (c != ' ' && c != '\t' && c != '\n'))
{
is.unsetf(ios_base::skipws);
is >> c;
if(is.eof())
{
delete[] A;
A = car;
return;
}
if(c != ' ' && c != '\t' && c != '\n')
{
if(wordSize == arrSize)
{
reSize(car, arrSize, arrSize * 2);
}
*(car + wordSize) = c;
}
wordSize++;
}
is.setf(ios_base::skipws);
delete[] A;
A = car;
}
void printMessage(const char* word1, const char* word2, const char* message)
{
cout << message << endl;
cout << "word1: " << word1 << endl << "word2: " << word2 << endl;
}
I thought I got it all done just fine. Keep in mind that I added the "&" operator after each of the pointer parameters already. Here is how they were before:
void stringCopy(char *&A, char *B);
bool stringCompare(char *A, char *B);
void stringConcatenation(char *&A, char *B); //added const to make sure b
is never changed
int stringPosition(char *A, char B);
int stringLength(char *&A);
But, when I got to class, my teacher said we weren't allowed to change the function headers in any way. So, I am stuck passing by value for the assignment. The problem is that I have no way of changing the c-strings outside the editing functions now. Any changes I do to them stay inside there.
It all compiles just fine, and, if I make the pointers pass-by-reference, the program runs flawlessly. I am just wondering how I could change the values of the c-strings outside of the editing functions. This assignment is starting to become a pain (so many f***ing restrictions).
I think what your teacher wants you to do is to change the value at the character pointer instead of creating a new string.
So instead trying to reassigning parameter A to a new char* you change the value that A points to in memory. That way the method that called your function still points to that same memory and when they access that location the get the value you changed from within your function.

Function Pointers in C++ Class Files

I've been trying to work with function pointers for quite a bit now, and to no avail. I've been working with a few friends to create a C++ 11 library to make creating ASCII games easier, and I've personally been working on creating a menu class. The beef of the class is complete, but one issue - I can't get the buttons to call functions. I always get the error:
terminate called after throwing an instance of 'std::bad_function_call'
what(): bad_function_call
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Obviously the error lies somewhere in the pointers, but I can't solve it for the life of me. Thanks for the help in advance.
Menu.h
#ifndef MENU_H
#define MENU_H
using namespace std;
#include <functional>
#include <string>
#include <map>
class Menu {
public:
int numberOfOptions;
map<int, string> options;
int currentSelection;
string title;
Menu();
Menu(int initialNumberOfOptions, map<int, string> initialOptions, int initialSelection);
void display();
void waitForInput();
void attachOptionAction(int option, void (*function)());
private:
map<int, void (*std::function<void()>)> optionActions;
void executeOptionAction(int option);
};
#endif
Menu.cpp
#include "Menu.h"
#include <windows.h>
#include <iostream>
#include <conio.h>
Menu::Menu(int initialNumberOfOptions, map<int, string> initialOptions, int initialSelection) {
title = "";
numberOfOptions = initialNumberOfOptions;
options = initialOptions;
currentSelection = initialSelection;
}
void Menu::display() {
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), {0, 0});
for(int i = 0; i < 10; i++) {
cout << " " << endl;
}
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), {0, 0});
if(title != "") {
cout << title << endl << endl;
}
for(int i = 0; i < numberOfOptions; i++) {
if(i == currentSelection - 1) {
cout << "[ " << options[i] << " ]" << endl;
} else {
cout << options[i] << endl;
}
}
waitForInput();
}
void Menu::waitForInput() {
char input;
while(!kbhit());
input = getch();
if(input == 72 && currentSelection > 1) {
currentSelection--;
} else if (input == 80 && currentSelection < numberOfOptions) {
currentSelection++;
} else if (input == 13) {
if(currentSelection == 1) {
executeOptionAction(1);
}
return;
}
display();
}
void Menu::attachOptionAction(int option, std::function<void()> function) {
optionActions[option] = function;
}
void Menu::executeOptionAction(int option) {
(optionActions[option])();
}
test.cpp
#include "Menu.h"
#include <unistd.h>
#include <iostream>
#include <iomanip>
#include <map>
void test() {
cout << "Hello, World!";
}
int main() {
map<int, string> options;
options[0] = "Play";
options[1] = "Help";
options[2] = "Quit";
Menu menu(3, options, 1);
menu.title = "ASCII Game Library 2015";
menu.display();
void (*actionPointer)() = NULL;
menu.attachOptionAction(1, (*actionPointer));
return 0;
}
This is wrong. I'm not even sure what's that supposed to be.
map<int, void (*std::function<void()>)> optionActions;
It should be:
map<int, std::function<void()>> optionActions;
This here is also wrong. It would be correct if you hadn't imported std into your current namespace.
void attachOptionAction(int option, void (*function)());
It should be:
void attachOptionAction(int option, const std::function<void()> & action);
This here is also wrong. You can't name your argument function after you imported std into your namespace.
void Menu::attachOptionAction(int option, std::function<void()> function)
It should be:
void Menu::attachOptionAction(int option, const std::function<void()> & action)
This here is also wrong. You don't check if the function exists or that a valid function pointer was assigned to it. Which you haven't.
(optionActions[option])();
It should be:
// Attempt to find the action!
map<int, std::function<void()>>::iterator action = optionActions.find(option);
// Did we find anything?
if (action == optionActions.end())
{
return;
}
// Is the function assigned to this action valid?
if (action->second)
{
action->second();
}
You are attaching a null function pointer to an action and try to call it. And since there's no validation it does exactly that. Which is why you get that exception:
void (*actionPointer)() = NULL;
menu.attachOptionAction(1, (*actionPointer));
But I'm not even sure how even managed to compile it :/
EDIT:
I hope you can find this example to be informative on what you're looking for.
#include <map>
#include <string>
#include <cstdlib>
#include <iostream>
#include <functional>
class Menu
{
protected:
typedef std::function<int (Menu &)> Callback;
typedef std::map<int, Menu> SubMenus;
public:
Menu()
: m_Id(0), m_Name(""), m_Handler(nullptr)
{
}
Menu(int id, const std::string & name, Callback clbk)
: m_Id(id), m_Name(name), m_Handler(clbk)
{
}
Menu & operator [] (int id)
{
return m_Childrens.at(id);
}
int Enter()
{
int result = 0;
if (m_Handler)
result = m_Handler(*this);
return result;
}
void Insert(const Menu & menu)
{
m_Childrens[menu.m_Id] = menu;
}
void Insert(int id, const std::string & name, Callback clbk)
{
m_Childrens[id] = Menu(id, name, clbk);
}
void Remove(int id)
{
m_Childrens.erase(id);
}
int GetId() const
{
return m_Id;
}
const std::string & GetName() const
{
return m_Name;
}
const Callback & GetHandler() const
{
return m_Handler;
}
bool IsChildren(int id) const
{
return (m_Childrens.find(id) != m_Childrens.cend());
}
Menu & GetChildren(int id)
{
return m_Childrens.at(id);
}
const SubMenus & GetChildrens() const
{
return m_Childrens;
}
private:
int m_Id;
std::string m_Name;
Callback m_Handler;
SubMenus m_Childrens;
};
void ClearScreen()
{
system("cls");
}
int SharedMenuDisplay(const Menu & menu)
{
ClearScreen();
std::cout << "Welcome to " << menu.GetName() << std::endl;
for (const auto & m : menu.GetChildrens())
{
std::cout << "> " << m.second.GetId() << " - " << m.second.GetName() << std::endl;
}
std::cout << "> 0 - Go Back" << std::endl;
std::cout << "Please select a sub menu: ";
int choice;
std::cin >> choice;
return choice;
}
int Menu_Home(Menu & menu)
{
int choice;
int result = 0;
do {
ClearScreen();
std::cout << "Welcome to " << menu.GetName() << std::endl;
for (const auto & m : menu.GetChildrens())
{
std::cout << "> " << m.second.GetId() << " - " << m.second.GetName() << std::endl;
}
std::cout << "> 0 - To Leave" << std::endl;
std::cout << "Please select a sub menu: ";
std::cin >> choice;
if (choice != 0 && menu.IsChildren(choice))
result = menu.GetChildren(choice).Enter();
} while (choice != 0);
return result;
}
int Menu_A(Menu & menu)
{
int choice;
int result = 0;
do {
choice = SharedMenuDisplay(menu);
if (choice != 0 && menu.IsChildren(choice))
result = menu.GetChildren(choice).Enter();
} while (choice != 0);
return result;
}
int Menu_A_SubMenu_X(Menu & menu)
{
ClearScreen();
std::cout << "You have selected " << menu.GetName() << std::endl;
std::cout << "> Type something and press Enter to go back..." << std::endl;
std::string str;
std::cin >> str;
return 0;
}
int Menu_A_SubMenu_Y(Menu & menu)
{
ClearScreen();
std::cout << "You have selected " << menu.GetName() << std::endl;
std::cout << "> Type something and press Enter to go back..." << std::endl;
std::string str;
std::cin >> str;
return 0;
}
int Menu_A_SubMenu_Z(Menu & menu)
{
ClearScreen();
std::cout << "You have selected " << menu.GetName() << std::endl;
std::cout << "> Type something and press Enter to go back..." << std::endl;
std::string str;
std::cin >> str;
return 0;
}
int Menu_B(Menu & menu)
{
int choice;
int result = 0;
do {
choice = SharedMenuDisplay(menu);
if (choice != 0 && menu.IsChildren(choice))
result = menu.GetChildren(choice).Enter();
} while (choice != 0);
return result;
}
int Menu_B_SubMenu_X(Menu & menu)
{
ClearScreen();
std::cout << "You have selected " << menu.GetName() << std::endl;
std::cout << "> Type something and press Enter to go back..." << std::endl;
std::string str;
std::cin >> str;
return 0;
}
int Menu_B_SubMenu_Y(Menu & menu)
{
ClearScreen();
std::cout << "You have selected " << menu.GetName() << std::endl;
std::cout << "> Type something and press Enter to go back..." << std::endl;
std::string str;
std::cin >> str;
return 0;
}
int Menu_B_SubMenu_Z(Menu & menu)
{
ClearScreen();
std::cout << "You have selected " << menu.GetName() << std::endl;
std::cout << "> Type something and press Enter to go back..." << std::endl;
std::string str;
std::cin >> str;
return 0;
}
int Menu_C(Menu & menu)
{
ClearScreen();
std::cout << "You have selected " << menu.GetName() << std::endl;
std::cout << "> Type something and press Enter to go back..." << std::endl;
std::string str;
std::cin >> str;
return 0;
}
int main(int argc, char **argv)
{
Menu home(-1, "Home", &Menu_Home);
home.Insert(1, "Menu Item A", &Menu_A);
home.Insert(2, "Menu Item B", &Menu_B);
home.Insert(3, "Menu Item C", &Menu_C);
home.GetChildren(1).Insert(1, "Sub Menu Item X", &Menu_A_SubMenu_X);
home.GetChildren(1).Insert(2, "Sub Menu Item Y", &Menu_A_SubMenu_Y);
home.GetChildren(1).Insert(3, "Sub Menu Item Z", &Menu_A_SubMenu_Z);
home[2].Insert(1, "Sub Menu Item X", &Menu_B_SubMenu_X);
home[2].Insert(2, "Sub Menu Item Y", &Menu_B_SubMenu_Y);
home[2].Insert(3, "Sub Menu Item Z", &Menu_B_SubMenu_Z);
return home.Enter();
}

Undefined reference to a method in another class file, how to fix?

I've been working on a program that will do a couple of equations in regards to audio, SPL, etc.
I decided to have the main class file present the user with an option to choose what equation he wants to do, while the equations are housed in another class file.
Atm, the main class file is setup just to test maxPeakSPL(), yet I can't get it to run.
main.cpp
//Kh[a]os
#include "equations.h"
#include <iostream>
void mainLoop();
int maxSPL = 0;
int main()
{
std::cout << "Created by Kh[a]os" << std::endl << std::endl;
mainLoop();
return 0;
}
void mainLoop()
{
std::cout << "hi";
maxSPL = equations::maxPeakSPL();
std::cout << std::endl << maxSPL << "db" << std::endl << std::endl;
}
equations.h
#ifndef EQUATIONS_H
#define EQUATIONS_H
#include <string>
class equations
{
public:
equations();
static int maxPeakSPL();
protected:
private:
};
#endif // EQUATIONS_H
equations.cpp
#include "equations.h"
#include <iostream>
#include <string>
equations::equations()
{
}
static int maxPeakSPL()
{
int Sens = 0;
double Distance = 0;
int Watts = 0;
int sWatts = 2;
int eWatts = 0;
double maxSPL = 0;
double counter = 0;
double wall = 0;
std::string corner = "";
bool v = true;
std::cout << "Sensitivity (db): " << std::endl;
std::cin >> Sens;
std::cout << "Amplification (watts): " << std::endl;
std::cin >> Watts;
std::cout << "Listening Distance (meters): " << std::endl;
std::cin >> Distance;
std::cout << "Distance from Wall (ft): " << std::endl;
std::cin >> wall;
std::cout << "Are you they in a corner? (y/n): " << std::endl;
std::cin >> corner;
maxSPL = Sens - (Distance*3 - 3);
while(v == true)
{
if (sWatts > Watts)
{
v = false;
eWatts = sWatts;
sWatts = sWatts/2;
Watts = Watts-sWatts;
counter = (double)Watts/(double)eWatts;
counter = counter*3;
maxSPL = maxSPL + counter;
}
if (v == true)
{
maxSPL = maxSPL + 3;
sWatts = sWatts*2;
}
}
if (wall <= 4)
maxSPL = maxSPL + 3;
if (corner == "Y" || corner == "YES" || corner == "y" || corner == "yes")
maxSPL = maxSPL + 3;
return maxSPL;
}
The error I get when I run it is: undefined reference to `equations::maxPeakSPL()'
I haven't a clue how to fix this, any assistance would be great. Thank you.
In your main, try putting the function before the main block. Include an underscore before the name of your directives/flags.

Printing a singly linked list using classes

I am making a program for singly linked lists using multiple files and classes.
I have to have a Node.h, LinkedList.h, Node.cpp, LinkedList.cpp, and a main.cpp
I was having other problems but now my printList() function just prints "List()" instead of "List(node 1, node2, etc...)"
I think my insert might be the problem because my searchNode() doesn't work right either, it always says node not found.
Here is the code I have: (I can't change the Node.h and LinkedList.h files)
Node.h:
//
// Node.h
// Linked Lists
//
#ifndef Linked_Lists_Node_h
#define Linked_Lists_Node_h
class Node
{
public:
Node(int data);
int data;
Node *next;
};
#endif
LinkedList.h:
//
// LinkedList.h
// Linked Lists
//
#ifndef Linked_Lists_LinkedList_h
#define Linked_Lists_LinkedList_h
#include "Node.h"
class LinkedList
{
private:
Node *head;
public:
LinkedList();
void addNode(int data);
void removeNode(int data);
bool searchNode(int data);
void printList();
};
#endif
Node.cpp
//
// Node.cpp
// Linked Lists
//
#include <iostream>
#include <cstdlib>
#include "LinkedList.h"
#include "Node.h"
using namespace std;
Node::Node(int data) {};
LinkedList.cpp
//
// LinkedList.cpp
// Linked Lists
//
#include <iostream>
#include <cstdlib>
#include "LinkedList.h"
#include "Node.h"
using namespace std;
LinkedList::LinkedList()
{
head = NULL;
}
void LinkedList::addNode(int data)
{
Node *newNode;
newNode->data = data;
newNode->next = NULL;
Node *tmp = head;
if(tmp != NULL)
{
while(tmp->next != NULL)
{
tmp = tmp->next;
}
tmp->next = newNode;
}
cout << "Node added" << endl;
printList();
}
void LinkedList::removeNode(int data)
{
Node *tmp = head;
if(tmp == NULL)
{
cout << "No node removed" << endl;
return;
}
if(tmp->next == NULL)
{
delete tmp;
head = NULL;
}
else
{
Node *previous;
do
{
if(tmp->data == data)
{
break;
}
previous = tmp;
tmp = tmp->next;
}
while(tmp != NULL);
previous->next = tmp->next;
delete tmp;
}
cout << "Node removed" << endl;
printList();
}
bool LinkedList::searchNode(int data)
{
Node *tmp = head;
while(tmp != NULL)
{
if(tmp->data == data)
{
cout << "Node found" << endl;
printList();
return true;
}
tmp = tmp->next;
}
cout << "Node not found" << endl;
printList();
return false;
}
void LinkedList::printList()
{
Node *tmp = head;
if(tmp == NULL)
{
cout << "List()" << endl;
return;
}
if(tmp->next == NULL)
{
cout << "List(" << tmp->data << ")";
}
else
{
do
{
cout << "List(" << tmp->data;
cout << ", ";
tmp = tmp->next;
}
while (tmp != NULL);
cout << ")" << endl;
}
}
main.cpp
//
// main.cpp
// Linked Lists
//
#include <iostream>
#include <cstdlib>
#include "LinkedList.h"
#include "Node.h"
#include "LinkedList.cpp"
using namespace std;
int main ()
{
LinkedList list;
int data;
int choice;
while(1)
{
cout << " Select:" << endl;
cout << "1 to add a node" <<endl;
cout << "2 to remove a node" << endl;
cout << "3 to search for a node" << endl;
cout << "4 to exit" << endl;
cout << endl;
cin >> choice;
switch(choice)
{
case 1: //insertion
cout << "Enter node: ";
cin >> data;
list.addNode(data); //add a node
break;
case 2: //deletion
cout << "Enter node: ";
cin >> data;
list.removeNode(data); //remove a node
break;
case 3: //search
cout << "Enter node: ";
cin >> data;
list.searchNode(data); //search for a node
break;
case 4:
exit(0); //exit the program
break;
default: //default case
cout << "Please enter a valid choice (1 - 4)!" << endl;
break;
}
}
return 0;
}
If you could help me figure out my problem I would greatly appreciate it.
You're not adding any nodes. If head is NULL, your add Node becomes:
void LinkedList::addNode(int data)
{
Node *newNode;
newNode->data = data;
newNode->next = NULL;
Node *tmp = head;
if(tmp != NULL)
{
//this never gets executed
}
cout << "Node added" << endl;
printList();
}
You need to treat this case (first insertion):
void LinkedList::addNode(int data)
{
Node *newNode;
newNode->data = data;
newNode->next = NULL;
Node *tmp = head;
if(tmp != NULL)
{
while(tmp->next != NULL)
{
tmp = tmp->next;
}
tmp->next = newNode;
}
else
{
head = newNode;
}
cout << "Node added" << endl;
printList();
}
This will create the head if it doesn't exist already.
Are you using a debugger? It would be much easier (for you) if you did.