Why does my overloading constructor produces a crash? - visual-c++

Basically, when overloading operator (operator--) constructor is called
my program crashes, changing classes arrays from dynamic, to static ones,
solves the problem, why is that?
If classes arrays are change from dynamic to static, overloading works
great, but this isn't a solution I am looking for.
The working version with static array:
#include <iostream>
#include<string>
using namespace std;
const int TABLE = 10;
class Player()
{
private:
int health;
string A[TABLE][TABLE];
public:
Player()
{
health = 17;
for (int i = 0; i < TABLE; i++)
{
for (int j = 0; j < TABLE; j++)
A[i][j] = "-";
}
}
Player(int new_health)
{
health = new_health;
}
Player operator--()
{
health--;
return Player(health);
}
~Player(){}
};
int main()
{
Player p1; // Creates object p1 and calls Player(), initializing
health variable, and string A array.
--p1; // Decrements p1 health value
return 0;
}
Dynamic array version:
#include <iostream>
#include<string>
using namespace std;
const int TABLE = 10;
class Player()
{
private:
int health;
string **A;
public:
Player()
{
health = 17;
A = new string*[TABLE];
for (int i = 0; i < TABLE; i++)
{
A[i] = new string[TABLE];
}
for (int i = 0; i < TABLE; i++)
{
for (int j = 0; j < TABLE; j++)
A[i][j] = "-";
}
}
Player(int new_health)
{
health = new_health;
}
Player operator--()
{
health--;
return Player(health);
}
~Player()
{
for (int i = 0; i < TABLE; i++)
delete[] A[i];
delete[] A;
}
};
int main()
{
Player p1; // Creates object p1, calls Player(), set health value,
initializes dynamic array
--p1; // Produces a crash with exit status -1
return 0;
}
No error messages, the crash doesn't happen at the health = new_health
part, it crashes as soon as Player(int new_health) constructor has done
its job. How can dynamic arrays affect overloading constructor and cause a crash?

The error is occurring because the new player instance that you create in your -- overload is getting destructed; however, your constructor overload never initialized your dynamic array. So when the destructor is called you are trying to delete unallocated memory.

Related

CS50 Plurality Problem, error: use of undeclared identifier 'i'

Trying to solve the pset3 plurality problem for the CS50 class, line 93 of my code has been the issue, I'm having some trouble solving the last part of the problem set, printing the winner.
I think the vote totals section is okay, but I can't get the code right for the winners section. When I run the code I receive the following error message:
error: use of undeclared identifier 'i' printf("%s\n", candidates[i].name);
#include <cs50.h>
#include <stdio.h>
#include <string.h>
// Max number of candidates
#define MAX 9
// Candidates have name and vote count
typedef struct
{
string name;
int votes;
}
candidate;
// Array of candidates
candidate candidates[MAX];
// Number of candidates
int candidate_count;
// Function prototypes
bool vote(string name);
void print_winner(void);
int main(int argc, string argv[])
{
// Check for invalid usage
if (argc < 2)
{
printf("Usage: plurality [candidate ...]\n");
return 1;
}
// Populate array of candidates
candidate_count = argc - 1;
if (candidate_count > MAX)
{
printf("Maximum number of candidates is %i\n", MAX);
return 2;
}
for (int i = 0; i < candidate_count; i++)
{
candidates[i].name = argv[i + 1];
candidates[i].votes = 0;
}
int voter_count = get_int("Number of voters: ");
// Loop over all voters
for (int i = 0; i < voter_count; i++)
{
string name = get_string("Vote: ");
// Check for invalid vote
if (!vote(name))
{
printf("Invalid vote.\n");
}
}
// Display winner of election
print_winner();
}
// Update vote totals given a new vote
bool vote(string name)
{
for (int i = 0; i < candidate_count; i++)
{
if (strcmp(name, candidates[i].name) == 0)
candidates[i].votes++;
}
return true;
return false;
}
// Print the winner (or winners) of the election
void print_winner(void)
{
int maxvote = 0;
for (int i = 0; i < candidate_count; i++)
{
if (candidates[i].votes > maxvote)
maxvote = candidates[i].votes;
}
printf("%s\n", candidates[i].name);
return;
}
The i variable is defined only within the context of your loop. When the loop is over, where your print statement tries to print candidates[i].name but i is not defined anymore. Just like how you save your max number of votes, you also need to save your candidate index in a value declared outside of your loop.
int maxvote = 0;
int winnerIndex;
for (int i = 0; i < candidate_count; i++)
{
if (candidates[i].votes > maxvote) {
maxvote = candidates[i].votes;
winnerIndex = i;
}
}
printf("%s\n", candidates[winnerIndex].name);

I'm not Sure why the incompatible intializer is not compatible with the parameter type int

Basically, I want to display my test scores and the average of them but I am unable to because of these errors
I've tried to take void display and put it in the class and declare it in main but that didn't work
#include <iostream>
#include <string>
using namespace std;
class TestScore
{
public:
TestScore() {};
TestScore(int arr[], int SIZE) {};
void testAvg(int arr[], int SIZE);
void displayArray(int arr[], int Size);
};
void TestScore::testAvg(int arr[], int SIZE)
{
int sum = 0;
for (int i = 0; i < SIZE; i++)
{
sum = sum + arr[i];
try
{
if ((arr[i] > 100) || (arr[i] < 0))
{
throw(1);
}
}
catch (int n)
{
cout << "Error" << endl;
}
}
int average = sum / SIZE;
}
void TestScore::displayArray(int arr[], int SIZE)
{
for (int i = 0; i < SIZE; i++)
{
cout << arr[i] << endl;
}
}
void main()
{
const int SIZ = 5;
int Grade[SIZ] = { 89,65,99,100,81 };
TestScore T(int Grade, int SIZ);
T(Grade, SIZ).testAvg(Grade, SIZ);
T(Grade, SIZ).displayArray(Grade, SIZ);
system("pause");
}
I expect it to display the average of my score so basically, I want to have an array of 5 test scores displaying and then the average of them.
TestScore T(int Grade, int SIZ); declares a function named T, taking two parameters of type int. You then call that function, passing a parameter of type int[5] - not an int. Hence the error message.
Further, that function is not implemented anywhere. Frankly, I don't understand what you are trying to do with that function declaration; it makes little sense.

How to initialize a number of variables within a for loop in Arduino

I'd like to initialize a bunch of variables by calling them in a for loop like this. The effect I'm hoping for is that I'd have three variables at the end aVar = 1, bVar =2, and cVar = 3.
char* variables[] = { "aVar", "bVar", "cVar"};
int values[] = { 1, 2, 3};
void setup(){
for (int i = 0; i < 3; i++){
int String(variables[i]) = values [i];
Serial.println(variables[i]);
}
}
Is there a way to do this?
What you seem to be suggesting is creating a variable at run time whose name is also variable which is not possible. What you could do is create a map and have your keys be entries from variables array and your values be entries from values array.
using namespace std;
int main()
{
char* variables[] = { "aVar", "bVar", "cVar"};
int values[] = { 1, 2, 3};
map<string, int> VariablesMap;
for(int i = 0; i < 3 ; i ++)
{
VariablesMap[variables[i]] = values[i];
}
return 0;
}

Multithreading in C++ using reference classes - ThreadStart constructor issues?

I appreciate any help, and would like to thank you in advance. I'm working on a project for one of my classes. Essentially performing merge sort using multithreading and reference classes. In main I'm just trying to create an initial thread that will begin the recursive mergesort. Each time the array is split a new thread is spawned to handle that subroutine. I don't need all of it done, i just don't under stand why my Thread constructor and ThreadStart delegate are not working. Thanks again!!
#include <iostream>
#include <vector>
#include <string>
#include <time.h>
#include <cstdlib>
using namespace System;
using namespace System::Threading;
public ref class MergeSort
{
private: int cnt;
public: MergeSort()
{
cnt = 0;
}
public: void mergeSort(char a[], int from, int to)
{
Thread^ current = Thread::CurrentThread;
if(from == to)
return;
int mid = (from + to)/2;
//Sort the first and the second half
//addThread(a, from, mid);
//addThread(a, mid+1, to);
//threads[0]->Join();
//threads[1]->Join();
merge(a, from, mid, to);
}
public: void merge(char a[], int from, int mid, int to)
{
Thread^ current = Thread::CurrentThread;
while (current ->ThreadState == ThreadState::Running)
{
int n = to-from + 1; // Size of range to be merged
std::vector<char> b(n);
int i1 = from; //Next element to consider in the first half
int i2 = mid + 1; //Next element to consider in the second half
int j = 0; //Next open position in b
//As long as neight i1 or i2 is past the end, move the smaller element into b
while(i1 <= mid && i2 <= to)
{
if(a[i1] < a[i2])
{
b[j] = a[i1];
i1++;
}
else
{
b[j] = a[i2];
i2++;
}
j++;
}
//Copy any remaining entries of the first half
while(i1 <= mid)
{
b[j] = a[i1];
i1++;
j++;
}
while(i2 <= to)
{
b[j] = a[i2];
i2++;
j++;
}
//Copy back from temporary vector
for(j = 0; j < n; j++)
a[from+j] = b[j];
}
}
};
void main()
{
char A[10];
for(int i = 0; i < 10; i++)
{
A[i] = ((char) ((rand() % (122-65)) + 65));
}
array<Thread^>^ tr = gcnew array<Thread^>(10);
MergeSort^ ms1 = gcnew MergeSort();
ThreadStart^ TS = gcnew ThreadStart(ms1, &MergeSort::mergeSort(A, 0, 10));
tr[0] = gcnew Thread(TS);
tr[0] -> Start();
system("pause");
}
The issue you are facing here is how to construct a ThreadStart delegate. You are trying to do too many things in the ThreadStart constructor. You cannot pass in arguments at this point because all it is looking for is a start location for the thread.
The delegate should be:
ThreadStart^ TS = gcnew ThreadStart(ms1, &MergeSort::mergeSort);
Since however you are passing in some state, I would recommend doing a bit more research on how that is done using C++\CLI. This MSDN topic should give you a start.
Edit:
Never mind, the problem was that I had to change the parameter of the method I tried to pass from Int32 to Object^.
I´m having a similar issue, though i think my problem are not the arguments. I´m passing those through during thread->Start().
I think my problem is rather that I´m trying to start the thread using a method of a ref class.
invalid delegate initializer -- function does not match the delegate type
Is the error I´m getting. Any Ideas?
void AddForcesAll() {
for (int index = 0; index < n; index++) {
Thread^ thread = gcnew Thread (gcnew ParameterizedThreadStart(this, &Bodies::AddForces));
thread->Start(index);
}
The Syntax worked fine for me for non referenced classes.

boost::shared_array assignment crashes application(VC++ 2010)

Modified the below circular queue code for my app.
This queue can hold 32 elements max and I have declared the elements as a structure array inside the class. For adding an element to the queue you have to call CreateElement() functions, which checks for a free element and returns an index. When I reuse an element after processing the following line in the CreateElement functions crashes
boost::shared_array<char> tData(new char[bufferSize]);
m_QueueStructure[queueElems].data = tData;
As per documentation, the assignment operator is supposed to destroy the earlier object and assign the new one. Why is it crashing? Can someone tell me where am I screwing?
#include "boost/thread/condition.hpp"
#include "boost/smart_ptr/shared_array.hpp"
#include <queue>
#define MAX_QUEUE_ELEMENTS 32
typedef struct queue_elem
{
bool inUse;
int index;
int packetType;
unsigned long compressedLength;
unsigned long uncompressedLength;
boost::shared_array<char> data;
}Data;
class CQueue
{
private:
int m_CurrentElementsOfQueue;
std::queue<Data> the_queue;
mutable boost::mutex the_mutex;
boost::condition_variable the_condition_variable;
Data m_QueueStructure[MAX_QUEUE_ELEMENTS];
public:
CQueue()
{
m_CurrentElementsOfQueue = 0;
for(int i = 0; i < MAX_QUEUE_ELEMENTS; i++)
{
m_QueueStructure[i].inUse = false;
m_QueueStructure[i].index = i;
}
}
~CQueue()
{
for(int i = 0; i < m_CurrentElementsOfQueue; i++)
{
int index = wait_and_pop();
Data& popped_value = m_QueueStructure[index];
popped_value.inUse = false;
}
m_CurrentElementsOfQueue = 0;
}
void push(Data const& data)
{
boost::mutex::scoped_lock lock(the_mutex);
the_queue.push(data);
lock.unlock();
the_condition_variable.notify_one();
}
bool empty() const
{
boost::mutex::scoped_lock lock(the_mutex);
return the_queue.empty();
}
bool try_pop(Data& popped_value)
{
boost::mutex::scoped_lock lock(the_mutex);
if(the_queue.empty())
{
return false;
}
popped_value=the_queue.front();
the_queue.pop();
return true;
}
int wait_and_pop()
{
boost::mutex::scoped_lock lock(the_mutex);
while(the_queue.empty())
{
the_condition_variable.wait(lock);
}
Data& popped_value=the_queue.front();
the_queue.pop();
return popped_value.index;
}
int CreateElement(int bufferSize, unsigned long _compressedLength,
unsigned long _uncompressedLength, int _packetType) /* Send data length for this function */
{
int queueElems = 0;
if(m_CurrentElementsOfQueue == 32)
{
CCommonException ex(QERROR, QUEUE_FULL, "Circular Buffer Queue is full");
throw ex;
}
for(queueElems = 0; queueElems < MAX_QUEUE_ELEMENTS; queueElems++)
{
if(m_QueueStructure[queueElems].inUse == false)
break;
}
boost::shared_array<char> tData(new char[bufferSize]);
m_QueueStructure[queueElems].data = tData;
m_QueueStructure[queueElems].inUse = true;
m_QueueStructure[queueElems].compressedLength = _compressedLength;
m_QueueStructure[queueElems].uncompressedLength = _uncompressedLength;
m_QueueStructure[queueElems].packetType = _packetType;
m_CurrentElementsOfQueue++;
return queueElems;
}
Data& GetElement(int index)
{
Data& DataElement = m_QueueStructure[index];
return DataElement;
}
void ClearElementIndex(Data& delValue)
{
m_CurrentElementsOfQueue--;
delValue.inUse = false;
}
};
for(queueElems = 0; queueElems < MAX_QUEUE_ELEMENTS; queueElems++) after looping queueElems has value 32 but in your m_QueueStructure only 32 elements so you trying to access m_QueueStructure[queueElems].data to 33rd element. That the problem.
EDIT: try use m_QueueStructure[queueElems].data.reset(new char[bufferSize]);
Solved the problem. Two changes I did. In the wait_and_pop function, I was returning an index rather than a Data&. When I returned Data&, that solved the assignment problem. Another crash was happening due to a memset of a shared_array.get(). Lesson learnt, never memset a shared_array or a shared_ptr.

Resources