Pointer to pointer gets EXC_BAD_ACCESS when calling function - c++

I have two classes, one called Handler and one called Dice. In my Handler class i have a private variable called Dice **dices and a public function called rollDices. And in my Dice class i have a function called toss that will randomize a number 1-6. The problem is that when the function rollDices is calling the function toss I get EXT_BAD_ACCESS in toss function. Does anyone know why, and have a solution for it?
My Handler.cpp:
void Handler::rollDices(){
Dice **allDices = new Dice*[this->nrOfDices];
this->dices = allDices;
dices[nrOfDices]= new Dice(nrOfDices);
int count =1;
for (int i = 0; i < this->nrOfDices; i++)
{
allDices[i]->toss();
cout << "Dice "<< count << ": " << allDices[i]->getValue() << endl;
count ++;
}
}
My Dice.cpp:
void Dice::toss(){
this->value = rand()%this->nrOfSides+1; //Value is a private int in Dice class
}
If you need more code i can post it, just tell me!

Dice **allDices = new Dice*[nrOfDices];
Allocates the top level pointer so now we have all of the rows in memory. When you add the columns
dices[nrOfDices]= new Dice(nrOfDices);
This does not add a new Dice to all of the rows. It adds a new Dice to one past the end of valid range of dices. What you need to do is use a loop and go through all of the rows and add a Dice to each one like
for (int i = 0; i < nrOfDices; i++)
dices[i] = new Dice(nrOfDices);

You are only allocating a single Dice object at index nrOfDices (which is of bounds by the way), if you want to allocate all Dice objects you need:
void Handler::rollDices(){
Dice **allDices = new Dice*[nrOfDices];
this->dices = allDices;
int count =1;
for (int i = 0; i < this->nrOfDices; i++)
{
dices[i] = new Dice(nrOfDices);
allDices[i]->toss();
cout << "Dice "<< count << ": " << allDices[i]->getValue() << endl;
count ++;
}
}

How about using modern C++? Try something like this:
void Handler::rollDice()
{
std::vector<Dice> allDice( nrOfDice );
int count = 1;
for( const auto & d : allDice )
{
d.toss();
cout << "Die "<< count << ": " << d.getValue() << endl;
++count;
}
}

Related

Why String is returning Junk values

Here I am using Data Structure Queues to change cards places using strings. User picks the top card than put it at last of the deck. The problem is that I need to return updated string to main. What it is returning is junk Values. I also tried to copy the string array and than returning that arraybut didn't work. Can anyone help?
#include<iostream>
#include<string>
using namespace std;
string CommunityChest(string Cards[]){
struct Que{
string cards[6];
int front =0;
int back=-1;
}ComQ;
string temp;
for(int i=0; i<5;i++)
{//Enqueue(Cards)
ComQ.back++;
if(ComQ.back<=5)
{
ComQ.cards[ComQ.back]=Cards[i];
}
else{
cout<<"Overflow";
}
}
//Display
for(int i=ComQ.front; i<=ComQ.back; i++)
{
cout<<ComQ.cards[i]<<endl;
}
//Del()
if(ComQ.front>=0)
{
temp=ComQ.cards[ComQ.front];
ComQ.front++;
}
cout<<endl<<"Pick the top Card"<<endl;
cout<<temp<<endl;
//EnQ the picked card
ComQ.back++;
if(ComQ.back<=5)
{
ComQ.cards[ComQ.back]=temp;
}
else{
cout<<"Overflow";
}
cout<<endl<<"After Inserting top card:"<<endl;
//Display
string newQ1[5];
for (int i=ComQ.front; i<=ComQ.back; i++) //Making an alternate array to copy Comq.cards array data
{
newQ1[i]=ComQ.cards[i];
}
for(int i=0; i<5; i++)
{
return newQ1[i]; //trying to return string array
//cout<< newQ1<<endl;
}
}
int main(){
string cards[5]{ "1 Advance ........",
"2. It is your ...........",
"3. You have won .............",//Cards as strings
"4. From sale of..............",
"5. Pay Hospital............"};
string newQ1=CommunityChest(cards);
for(int i=0; i<5; i++)
cout << newQ1[i] << endl;
return 0;
}
There are some issues with this code as mentioned in the comments, you are trying to do a return in a loop, this may look okay but it's wrong since a return can get you out of the function. But it seems like you want to return an array of strings.
A fix for this function would be like this:
#include <iostream>
std::string* CommunityChest(std::string Cards[]) {
struct Que {
std::string cards[6];
int front = 0;
int back = -1;
} ComQ;
std::string temp;
for (int i = 0; i < 5; i++) { // Enqueue(Cards)
ComQ.back++;
if (ComQ.back <= 5) {
ComQ.cards[ComQ.back] = Cards[i];
}
else {
std::cout << "Overflow";
}
}
// Display
for (int i = ComQ.front; i <= ComQ.back; i++) {
std::cout << ComQ.cards[i] << std::endl;
}
// Del()
if (ComQ.front >= 0) {
temp = ComQ.cards[ComQ.front];
ComQ.front++;
}
std::cout << std::endl
<< "Pick the top Card" << std::endl;
std::cout << temp << std::endl;
// EnQ the picked card
ComQ.back++;
if (ComQ.back <= 5) {
ComQ.cards[ComQ.back] = temp;
}
else {
std::cout << "Overflow";
}
std::cout << std::endl
<< "After Inserting top card:" << std::endl;
// Display
// Creating a dynamic array to store the values
std::string* newQ1 = new std::string[5];
for (int i = ComQ.front, j = 0; i <= ComQ.back && j < 5; i++, j++) {// Making an alternate array to copy Comq.cards array data
newQ1[j] = ComQ.cards[i];
}
return newQ1; // Returning the dynamic array
}
int main()
{
std::string cards[5]{
"1 Advance ........",
"2. It is your ...........",
"3. You have won .............", // Cards as strings
"4. From sale of..............",
"5. Pay Hospital............"
};
std::string* newQ1 = CommunityChest(cards);
for(int i = 0; i < 5; i++) {
std::cout << newQ1[i] << std::endl;
}
delete[] newQ1; // Deleting the array
return 0;
}
The output will be:
1 Advance ........
2. It is your ...........
3. You have won .............
4. From sale of..............
5. Pay Hospital............
Pick the top Card
1 Advance ........
After Inserting top card:
2. It is your ...........
3. You have won .............
4. From sale of..............
5. Pay Hospital............
1 Advance ........
In this fix, I'm returning a dynamically allocated array of strings because a static array will be destroyed once the scope ends, it would be better sometimes to use other ways to allocate memory such as std::unique_ptr<> or std::shared_ptr<>, but I'd suggest you learn how to do it yourself first then use those when needed.
EDIT:
You can also return an std::array<>, I suggest you to read about it as C-Style arrays cannot be returned in you way that you tried and can't be returned without using dynamic allocation, so an std::array<> can be a good replacement over std::string* in this case

Issue With Freeing Dynamically Allocated Memory In C++

Before my program can free up memory and end it crashes. Crashes seem to happen on transition from the function UserDataCollection and back to main. This is only my second program using pointers so I'm still quite the newbie considering the whole point of c++ is to use pointers.
Here is the aforementioned code:
#include <iostream>
//Prototypes
void UserDataCollection(int * &movieData_ptr, int &numSurveyed); // Movie Statistics
void DisplayOutput(int *movieData_ptr, int numSurveyed); //Mean, Median, Mode (Display To Console)
//Global Constants
int main()
{
//Variables
int numSurveyed = 0;
//Pointers
int * movieData_ptr = nullptr;
movieData_ptr = new int[numSurveyed];
//"Program Start"
std::cout << "Program start...\n\n";
UserDataCollection(movieData_ptr, numSurveyed);
DisplayOutput(movieData_ptr, numSurveyed);
//Release Memory
delete[] movieData_ptr;
std::cout << "Memory Cleared.";
return 0;
}
void UserDataCollection(int * &movieData_ptr, int &numSurveyed)
{
//Get Number of Students Surveyed
std::cout << "How many students were surveyed: ";
std::cin >> numSurveyed;
//Student Data Input Loop
for (int i = 0; i < numSurveyed; i++)
{
//Get Student Data
std::cout << "Enter How many movies student " << i + 1 << " has seen in ONE month: ";
std::cin >> *(movieData_ptr + i);
//Validation Check
while (*(movieData_ptr + i) >= 337)
{
std::cout << "\nImpossible value!" << std::endl
<< "Hours in a month: 730. Average movie length: 130 minutes."
<< "Total Possible movies: 337";
std::cout << "\n\nEnter How many movies student " << i + 1 << " has seen in ONE month: ";
std::cin >> *(movieData_ptr + i);
} //end while (Validation Check)
} // end for (Data Input)
}
void DisplayOutput(int *movieData_ptr, int numSurveyed)
{
//Display loop for pointer array
for (int i = 0; i < numSurveyed; i++)
{
std::cout << *(movieData_ptr + i) << " ";
}
//End Message
std::cout << "\n\nProgram end.";
}
You never allocated any memory.
int numSurveyed = 0;
//Pointers
int * movieData_ptr = nullptr;
movieData_ptr = new int[numSurveyed];
This is the equivalent of
int *movieData_ptr = new int[0];
You are allocating size of 0 ints. This is undefined behaviour. You can't do anything useful with that pointer without a segmentation fault. You need to either pre-allocate a certain amount, and make sure you don't overflow, or dynamically allocate every time you plan to add data.
Since this is C++, it's probably better not to use raw pointers, but use vector or something instead.
Sorry:
From 5.3.4/7
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements.
From 3.7.3.1/2
The effect of dereferencing a pointer returned as a request for zero size is undefined.

C++: When using a value called from a getter method of an object, a random negative int is outputted?

The following is my file TotalTemplate.cpp:
#include <iostream>
#include "conio.h"
using namespace std;
template<class T>
class TotalTemplate{
public:
//protected:
T* items;
int itemsAdded;
int amountOfItems;
//public:
//Exception for trying to add items when its passed its limit
class TooManyItems{ };
//Exception for trying to call total before the total has been reached
class IncompleteTotal{ };
TotalTemplate(int amountOfItems){
TotalTemplate::amountOfItems = amountOfItems;
items = new T[amountOfItems];
itemsAdded = 0;
}
TotalTemplate(int amountOfItems, T firstItem){
TotalTemplate::amountOfItems = amountOfItems;
items[] = new T[amountOfItems];
items[0] = firstItem;
itemsAdded = 1;
}
void addItem(T item){
if (itemsAdded >= amountOfItems)
throw TooManyItems();
else{
items[itemsAdded-1] = item;
itemsAdded++;
}
}
//Returns the amount of items added so far
int getAmountAdded(){
return itemsAdded;
}
T getTotal(){//Here is the method definition that is giving me problems
if (itemsAdded < amountOfItems)
throw IncompleteTotal();
else{
T total=items[0];
for (int i = 1; i < itemsAdded; i++)
total += items[i];
return total;
}
}
};
void main(){
//using int to fill the generic type T
cout << "Enter the amount of items to be totaled: ";
int totalAmountOfItems = getInt();
TotalTemplate<int> *total=new TotalTemplate<int>(totalAmountOfItems);
while (true){
cout << total->getAmountAdded() << " items added so far!\nSelect one of the following actions to take.\n";
cout << "(1) Add an item.\n";
cout << "(2) View total.\n";
cout << "(3) Exit Program.\n";
switch (menuSelect(3)){
case 1://Add an item
try{
cout << "Enter a number to add: ";
int item = getInt();
total->addItem(item);
}
catch (TotalTemplate<int>::TooManyItems){
cout << "\nItems given exceeds expected limit.\n\n";
}
break;
case 2://View Total
try{
int totalInt = total->getTotal(); //Here is my problem
cout << "The total is: " << totalInt << endl<<endl;
}
catch (TotalTemplate<int>::IncompleteTotal){
cout << "\nRunning Total has not yet reached total amount of items yet.\n\n";
}
break;
case 3: //Exit program
return;
}
}
cout << "\n\nExiting program...";
_getch();
}
The problem I'm getting is in the main method, when I call total.getTotal(), instead of return an expected int, being the total of all the items added together, I get a totally random int outputted: -842150451
My guess is that it's outputting something instead of the value returned from getTotal(), but I'm not sure how or why or how to fix it. I come from a Java background so I feel like I'm out of habit doing improper oop C++ practice.
Also, getInt() and menuSelect() are methods I have reused from previous codes multiple times, so I excluded them from the file for simplicity sake.
Does anyone know what I'm doing wrong?
this line in addItem
items[itemsAdded-1] = item;
should be
items[itemsAdded] = item;

C++ creating dynamic array of objects?

#include "resistor.h"
void main() {
srand(GetTickCount()); // Lewt's start by seeding the random number generator so that different runs of our program will always yield fifferent results
Resistor * pResistor; // Pointer to a resistor class
int numberOfResistors = 0; // Variable will hold the user choice of the number of resistors to be created
cout << "How many resistors do you want to create?" << endl; // prompt user
cin >> numberOfResistors; // Allow the user to enter the number of resistors to be created
pResistor = new Resistor[numberOfResistors]; // Create an array of objects of class resistor and assign its address to our pointer
// You will notice that there is a logic error here. All the resistors will have the same value. This
// is because they were all created at once. To address this issue we need to create each object
// of the class resistor separately. This means using a loop. This will be up to you to do
// It should be a very easy fix
for (int i = 0; i< numberOfResistors; i++) { // This loop will be used to display the resistor values
cout << "Resistor # " << i + 1 << " has a value of " << pResistor->getResistance() << " " << (char)234 << endl; // Display value of resistor pointed to by pResistor
}
cout << "So far, we have created " << pResistor->getNumerOfResistors() << " resistor(s)" << endl; // Display total number of resistors
delete[] pResistor; // Delete the array that was created and release the memory that was allocated.
} // end of main
I'm am woriking with this code for a class assignment. As you can probably see in the comments there is a logic error that my instructor put in there and I need to fix it. I tried putting the pResistor = new Resistor[numberOfResistors]; line inside a for loop that runs the number of times spcified by user input (instead of creating an array). The problem is still that each object is still created with the same value for ResistorObject.resistance
Any input would be much appreciated
EDIT: The following code is what i tried to explain above:
for (int i = 0; i < numberOfResistors; i++) {
pResistor = new Resistor[i]; // Create an array of objects of class resistor and assign its address to our pointer
}
This however will not compile as I get the error:
error C4703: potentially uninitialized local pointer variable 'pResistor' used
srand(GetTickCount());
Resistor * pResistor = NULL;
vector<Resistor*> resList;
int numberOfResistors = 50; // Use your cin cout here
for (size_t i = 0; i < numberOfResistors; i++)
{
pResistor = new Resistor;
// Assuming some sort of pResistor->SetResistance( /* val */ )
resList.push_back(pResistor);
}
for (int i = 0; i< numberOfResistors; i++) { // This loop will be used to display the resistor values
cout << "Resistor # " << i + 1 << " has a value of " << resList[i]->getResistance() << " " << (char)234 << endl; // Display value of resistor pointed to by pResistor
}
cout << "number of resistors : " << resList.size() << endl;
Each resistor needs its own reference, and all the references must be added to an ordered list. std::vector is used to make ordered lists

C++ Skipping elements in a one d array

I have an assignment with several ways to manipulate an array, but I'm having trouble with one of the parts.
I am reading about 50 numbers into the array from a .txt file
And for every odd location in the array (1,3,5,…), I have to subtract it from the previous even location (0,2,4,…) and store results in the odd location. Then I print out all values in the array.
Here is what I have so far:
void oddMinusEven(int ary[],int num)
{
for(int idx = ary[0]; idx<num; ary[idx+2])
{
ary[idx] = ary[idx+2]-ary[idx];
cout<<ary[idx]<<endl;
}
}
How do I do this? If you could provide some examples, that would be great.
This should do:
void oddMinusEven(int ary[], int num) {
for(int i = 1; i < num; i += 2) {
ary[i] = ary[i-1] - ary[i];
std::cout << "a[" << i << "] = " << ary[i] << std::endl;
}
}