So for an assignment I have to create a program that will create magic squares when the user inputs an odd number, I have most of the program done but for some reason when I try to populate the squares I get Unhandled exception at 0x00326315 in magic square.exe: 0xC0000005: Access violation reading location 0x00000000
I'm using classes and have the declaration for square as int **square;
Here is the code
#include<iostream>
#include<iomanip>
#include"MagicSquare.h"
using namespace std;
MagicSquare::MagicSquare(): size(0), maxNum(0), row(0), col(0), curNum(0) //Constructor initialize variables
{
}
MagicSquare::~MagicSquare() //Destructor
{
for (int i = 0; i < size; i++)
{
delete[] square[i];
}
delete[] square; //Delete the dynamically allocated memory
}
void MagicSquare::getSize() //Get the size of the magic square
{
cout << "Please enter an odd number for the number of rows/columns: ";
cin >> size;
while (size % 2 == 0) //Check to see if the number entered is odd
{
cout << "The number you entered is not odd, please enter an odd number: ";
cin >> size;
}
int **square = new (nothrow) int*[size];
for (int i = 0; i < size; i++)
{
square[i] = new (nothrow) int[size];
}
maxNum = size * size;
iCount = new (nothrow) int[size];
jCount = new (nothrow) int[size];
}
void MagicSquare::populateSquare()
{
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
square[i][j] = 0; //This is where the error occurs
}
}
curNum = 1;
col = (size - 1) / 2;
square[row][col] = curNum;
curNum += 1;
for (int i = 1; i <= maxNum; i++)
{
row = row - 1;
col = col + 1;
if (col >= size)
col = 0;
if (row < 0)
row = size - 1;
square[row][col] = curNum;
curNum += 1;
}
}
Header file
class MagicSquare
{
private:
int **square;
int size;
int maxNum;
int row;
int col;
int curNum;
int *iCount;
int *jCount;
public:
MagicSquare();
~MagicSquare();
void getSize();
void populateSquare();
void printSquare();
};
source file
#include"MagicSquare.h"
#include<iostream>
using namespace std;
int main()
{
MagicSquare mySquare;
int choice = 1;
while (choice == 1)
{
mySquare.getSize();
mySquare.populateSquare();
mySquare.printSquare();
cout << "\n\nWould you like to create another magic square? 1 for yes, 0 for no: ";
cin >> choice;
while (choice != 1 || choice != 0)
{
cout << "\nInvalid input: \nWould you like to create another magic square? 1 for yes, 0 for no: ";
cin >> choice;
}
}
system("pause");
return 0;
}
You are defining a local variable called square in your getSize() method here:
int **square = new (nothrow) int*[size];.
So you make space for the local variable but never for the class's field.
Change this line to
square = new (nothrow) int*[size];
Also seriously consider checking the results of the calls.
Access violation reading location 0x00000000 is telling you, that you are trying to access a NULL-pointer.
A reason could be, that at least one call of new failed. you should check when allocating the array:
int **square = new (nothrow) int*[size];
if(square == NULL)
//Handle error here
for (int i = 0; i < size; i++)
{
square[i] = new (nothrow) int[size];
if(square == NULL)
//Handle error here
}
But i guess thats not the reason. If I saw it right, you have two functions:
void MagicSquare::getSize()
void MagicSquare::populateSquare()
But the int **square is created in getSize, so if you call populate square, this variable does not exist anymore.
if your class is:
class MagicSquare
{
private:
int **square;
public:
//Methods
}
in getSize you have to store the address in the classes member variable, not a local one you just created:
square = new (nothrow) int*[size]; //without int **
Related
I started learning OOP in C++. I try to solve a task like this:
Create a class - a list based on a one-size-fits-all array of integers. Assign a constructor, a destructor, the functions of adding an element to the top (end) of the list, selecting an element from the list by number, sorting the list, showing the elements of the list to the top and to the bottom of the list."
In the delete function, the compiler constantly knocks out the same error:
E0852 the expression must be a pointer to the full type of the object My_4_Project C:\Users\artem\source\repos\Project4\My_4_Project\Source.cpp
Here is my code:
#include <iostream>
#include <algorithm>
using namespace std;
class Array {
private:
int* a;
unsigned int size;
int b, c = 0, d;
public:
Array();
Array(int s);
~Array();
int& operator[](int index);
void setarray();
void getarray();
void add();
void delet();
void sort();
};
Array::Array() {
size = 10;
a = new int[size];
for (size_t i = 0; i != size; i++) {
a[i] = 0;
}
}
Array::Array(int s) {
if (s > 0) {
size = s;
a = new int[size];
for (size_t i = 0; i != size; i++) {
a[i] = 0;
}
}
else cout << "Size can't be negativ";
}
Array::~Array() {
delete[]a;
}
int& Array::operator[](int index) {
if (index <= size) {
return a[index];
}
}
void Array::setarray() {
for (size_t i = 0; i != size; i++) {
cin >> a[i];
}
}
void Array::getarray() {
for (size_t i = 0; i != size; i++) {
cout << a[i] << " ";
}
}
void Array::add()
{
/* ? ? ? */ ;
}
void Array::delet() {
cin >> b;
for (int i = 0; i < size; i++)
{
if (b == a[i])
c++;
if (c > 2) delete a[i];
}
cout << c;
}
void Array::sort() {
int temp;
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - i - 1; j++) {
if (a[j] > a[j + 1]) {
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
for (int i = 0; i < size; i++) {
cout << a[i] << " ";
}
}
int main() {
cout << "Enter 10 number`s massive: ";
Array arr(10);
arr.setarray();
cout << endl;
arr.getarray();
cout << endl;
cout << "Sorted massive: ";
arr.sort();
cout << endl;
cout << "Witch symbol you wanna delete?: ";
arr.delet();
return 0;
}
The problem is that delete does not work as you think:
You can delete an object that you previously created with new (new returns a pointer, and delete expect that same pointer).
You can delete[] something that you previously created with new[]
But no mixing: you cannot delete an individual element when it was part of an array created with new[]
I will not do the exercise for you but the trick is to:
find the index of the duplicate element you want to get rid off,
copy every elements afterwards to one index before (i.e. a[j]=a[j+1], of course, making sure that j+1<size )
reduce the size by one.
So something like:
void Array::delet() {
cin >> b; // better put this in main() and pass it as argument
for (int i = 0; i < size; i++)
{
if (b == a[i])
{ // it'll be more than a single statement
c++;
if (c > 2) // found a duplicate
{ // NO delete a[i];
... // insert a loop to copy the next ones
// and reduce the size
... // EXTRA CAUTION: in this case the next element
// is again at offset i and not i++
}
}
}
cout << c; // ok, you can display the number of occurences counted
}
This program doubles the every second integer for the account number given and if the number is greater than 10 it is subtracted by 9. Then output whether the number entered is correct or not. Assuming that the account number is off 5 numbers. I wrote this program but does not get the answer for few number but got a correct answer for other number. Thanks for hint.
#include <iostream>
class AccountNumber {
private:
int size = 5;
int *p;
public:
AccountNumber() { int *p = new (std::nothrow) int[size]; }
~AccountNumber() { delete[] p; }
void getaccount() {
int acc;
std::cout << "Enter the account number: ";
std::cin >> acc;
for (int i = 0; i < size; i++) {
p[i] = acc % 10;
}
setaccount(p);
}
void setaccount(int a[]) {
for (int i = 0; i < size; i++) {
p[i] = a[i];
}
}
void doubles() {
AccountNumber at;
at.p = new int[size];
at.p = p;
for (int i = 0; i < size; i++) {
if (i % 2 == 1) {
at.p[i] = at.p[i] * 2;
if (at.p[i] > 10) {
at.p[i] = at.p[i] - 9;
}
}
}
p = at.p;
}
bool sum() {
bool ot;
int sum = 0;
for (int i = 0; i < size; i++) {
sum = sum + p[i];
}
int mod = sum % 10;
if (mod == 0) {
ot = true;
} else {
ot = false;
}
return ot;
}
void display(std::ostream &outs) {
bool ot = sum();
doubles();
outs << "Account number entered is ";
if (ot) {
outs << " correct.\n";
} else {
outs << " is not correct. \n";
}
}
};
int main(int argc, char const *argv[]) {
AccountNumber accn;
accn.getaccount();
accn.display(std::cout);
return 0;
}
Output
Enter the account number: 35556
Segmentation fault (core dumped)
I don't know where I'm going wrong.
The issue here is that you never allocate p. Look at your constructor:
AccountNumber()
{
int *p = new(std::nothrow) int[size];
}
Here you are defining a new pointer variable p, which will be used instead of the member pointer variable p you defined in the private fields. What happens here is that you are allocating an int array for a new variable p, but that variable p gets thrown out at the end of the constructor (and also causes a memory leak because of the dynamic allocation that will never be reclaimed).
What you should do here instead is simply assigning the new allocated array to the member pointer variable p without redefining it, ie.
AccountNumber() {
p = new (std::nothrow) int[size];
}
And to prevent such mistakes from happening again, you should consider using a specific naming convention for class members, such as m_ prefix (for example)
class AccountNumber {
private:
int m_size = 5;
int *m_p;
public:
AccountNumber() {
m_p = new (std::nothrow) int[size];
}
};
My code is supposed to print the Union and Intersection of two sets of integers.
Why do I get this warning?
Is it because I use dynamic arrays and it's size could be anything in runtime?
How can I fix it? My code works fine but this warning really bugs me.
P.S: I know it would be a lot easier to use std::vector but my teacher required to use arrays.
#include <iostream>
using namespace std;
void UnionFunc(int[],int,int[],int,int[],int&);
void IntersectionFunc(int[], int, int[], int, int[], int&);
int main() {
int* A;
int SizeA;
int* B;
int SizeB;
int* Union;
int UnionSize=0;
int* Intersection;
int IntersectionSize=0;
cout << "Enter the Size of First Set : "; cin >> SizeA;
A = new int[SizeA];
cout << "Enter the Size of Second Set : "; cin >> SizeB;
B = new int[SizeB];
Intersection = new int[SizeA >= SizeB ? SizeB : SizeA];
Union = new int[SizeA + SizeB];
for (int i = 0; i < SizeA; i++) {
cout << "Set A[" << i + 1 << "] = ";
cin >> A[i];
}
for (int i = 0; i < SizeB; i++) {
cout << "Set B[" << i + 1 << "] = ";
cin >> B[i];
}
UnionFunc(A,SizeA,B,SizeB,Union,UnionSize);
IntersectionFunc(A, SizeA, B, SizeB, Intersection, IntersectionSize);
cout <<endl<< "Union Set : ";
for (int i = 0; i < UnionSize; i++) {
cout << Union[i] << ",";
}
cout <<endl <<"Intersection Set : ";
for (int i = 0; i < IntersectionSize; i++) {
cout << Intersection[i] << ",";
}
system("pause>n");
return 0;
}
void UnionFunc(int A[],int SizeA, int B[],int SizeB, int Union[],int &UnionSize) {
//Adding First Array to Union Array
for (int i = 0; i < SizeA;i++) {
Union[i] = A[i];
UnionSize++;
}
//Checking if second array's elemnts already exist in union arry, if not adding them
bool exist;
for (int i = 0; i < SizeB; i++) {
exist = false;
for (int j = 0; j < UnionSize; j++) {
if (B[i] == Union[j] ) {
exist = true;
}
}
if (exist == false) {
Union[UnionSize] = B[i];
UnionSize++;
}
}
}
void IntersectionFunc(int A[], int SizeA, int B[], int SizeB, int Intersection[], int& IntersectionSize) {
for (int i = 0; i < SizeA; i++) {
for (int j = 0; j < SizeB; j++) {
if (A[i] == B[j]) {
Intersection[IntersectionSize] = A[i];
IntersectionSize++;
}
}
}
}
Is it because I use dynamic arrays and it's size could be anything in
runtime?
Yes! The compiler doesn't know (and, as your code is written, can't know) that both SizeA and SizeB will be 'valid' numbers - so the size of the three int arrays you create could be less than is required for the Intersection[i] 'read' to be valid.
A 'quick and dirty' fix for this is to provide a visible guarantee to the compiler that the arrays you create will be at least a certain size, like this:
A = new int[max(1,SizeA)]; // Compiler can now 'see' a minimum size
And similarly for the other allocations you make with the new[] operator.
(I have tested this with VS2019, adding the max(1,SizeA) and max(1,SizeB) 'fixes' to just the allocations of A and B and the warning is removed.)
Closed. This question needs debugging details. It is not currently accepting answers.
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.
Closed 4 years ago.
Improve this question
I am writing a dynamic matrix class that stores each non-zero value as a List of 3 elements [row,column,value]
I made a dynamic array class called "List", and class"Matrix" a List of list pointers.
My code to transpose the Matrix works:
void transpose(Matrix tripleList)
{
for (int i = 0; i < tripleList.getNumOfElem(); i++)
{
List* list = new List;
(*list).copy(*(tripleListMatrix.getAt(i)));
int temp = (*list).getAt(0);
(*list).set(0, (*list).getAt(1));
(*list).set(1, temp);
(*list).displayList();
cout << "\n";
}
}
it works when written directly in main() but gives error when in stand alone function. can anyone explains why and how to fix it?
Full code:
#include <iostream>
using namespace std;
class List //a dynamic int pointer array
{
private:
int capacity;
int numOfElem;
int *arr;
//initialize all values in capacity to 0
void initialize(int from)
{
for (int i = from; i < capacity; i++)
{
arr[i] = 0;
}
}
//double the capaicty, then initialize
void expand()
{
capacity *= 2;
int *tempArr = new int[capacity];
for (int i = 0; i < numOfElem; i++)
tempArr[i] = arr[i];
delete[] arr;
arr = tempArr;
initialize(numOfElem);
}
public:
List()//constructor
{
capacity = 10;
numOfElem = 0;
arr = new int[capacity];
}
~List()//destrcutor
{
delete[] arr;
}
//add int to the end of List
void append(int newElement)
{
if (numOfElem >= capacity)
expand();
arr[numOfElem++] = newElement;
}
//Copy all element of an input list to the end of List
void copy(List list)
{
for (int i = 0; i < list.getNumOfElem(); i++)
{
if (numOfElem >= capacity)
expand();
arr[numOfElem++] = list.getAt(i);
}
}
//get reference of the int at an index in te list
int* getAddress(int index)
{
if (index < 0 || index >= numOfElem)
throw ("Out of bounds exception!!!");
return &arr[index];
}
//change the value of at specific index
void set(int index, int value)
{
arr[index] = value;
}
//get int at an index in te list
int getAt(int index)
{
if (index < 0 || index >= numOfElem)
throw ("Out of bounds exception!!!");
return arr[index];
}
int getNumOfElem()
{
return numOfElem;
}
void displayList()
{
for (int i = 0; i < numOfElem; i++)
{
cout << arr[i] << " ";
}
}
};
class Matrix //a List of list pointers
{
private:
int capacity;
int numOfElem;
List* *arr;
void initialize(int from)
{
for (int i = from; i < capacity; i++)
{
arr[i] = new List;
}
}
void expand()
{
capacity *= 2;
List* *tempArr = new List*[capacity];
for (int i = 0; i < numOfElem; i++)
tempArr[i] = arr[i];
delete[] arr;
arr = tempArr;
initialize(numOfElem);
}
public:
Matrix()
{
capacity = 10;
numOfElem = 0;
arr = new List*[capacity];
}
~Matrix()
{
delete[] arr;
}
void append(List* newElement)
{
if (numOfElem >= capacity)
expand();
arr[numOfElem++] = newElement;
}
void set(int index, List* value)
{
arr[index] = value;
}
List* getAt(int index)
{
if (index < 0 || index >= numOfElem)
throw ("Out of bounds exception!!!");
return arr[index];
}
int getNumOfElem()
{
return numOfElem;
}
};
void transpose(Matrix tripleList)
{
for (int i = 0; i < tripleList.getNumOfElem(); i++)
{
{
List* list = new List;
(*list).copy(*(tripleListMatrix.getAt(i)));
int temp = (*list).getAt(0);
(*list).set(0, (*list).getAt(1));
(*list).set(1, temp);
(*list).displayList();
cout << "\n";
}
}
int main()
{
int m, n, input;
cout << "Please enter the number of rows and columns of the matrix :\n";
cin >> m >> n;
Matrix tripleListMatrix;
int k = 0;
cout << "Please enter the matrix : \n";
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
cin >> input;
if (input != 0)
{
tripleListMatrix.append(new List);
(*(tripleListMatrix.getAt(k))).append(i + 1);
(*(tripleListMatrix.getAt(k))).append(j + 1);
(*(tripleListMatrix.getAt(k))).append(input);
k++;
}
}
}
cout << "The triple list of matrix is:\n";
for (int i = 0; i < tripleListMatrix.getNumOfElem(); i++)
{
(*(tripleListMatrix.getAt(i))).displayList();
cout << "\n";
}
cout << "\n\n";
//transpose(tripleListMatrix);
//the code below is the same as in the function transpose but transpose gives error
for (int i = 0; i < tripleListMatrix.getNumOfElem(); i++)
{
List* list = new List;
(*list).copy(*(tripleListMatrix.getAt(i)));
int temp = (*list).getAt(0);
(*list).set(0, (*list).getAt(1));
(*list).set(1, temp);
(*list).displayList();
//cout << "\t" << list;
cout << "\n";
}
cout << "\n\n";
//checking that tripleListMatrix is unchanged
for (int i = 0; i < tripleListMatrix.getNumOfElem(); i++)
{
(*(tripleListMatrix.getAt(i))).displayList();
cout << "\n";
}
return 0;
}
List* *arr;
When you call transpose(), it makes a copy Matrix because you're not passing by reference. That copy just has a copy of the address for your List, not it's own List object. When the destructor runs on the copy, it clears up the allocated memory, but the original Matrix object in main still points to that same memory. When that object goes away, its destructor tries to free the same memory again and that's bad.
You probably meant:
void transpose(Matrix const & tripleList)
So that no copy is made when calling transpose(), but you should also explicitly delete the copy construtor of Matrix so it cannot be called
Matrix(Matrix const &) = delete;
or make an explicit Matrix copy constructor that makes a deep copy of the memory.
I'm writing an easy Game Of Life simulator. Everything works smoothly except at the very end, when the result is printed by cout I get a break error. I don't understand why and I would like to ask for your help.
variables
#include <iostream>
using namespace std;
struct cell
{
bool isAlive;
int posX;
int posY;
int numberOfAliveNeighbours;
char group;
};
int cellNumber;
cell *cellTable = new cell[cellNumber];
int numberOfTunrs;
main:
int main()
{
int x;
int y;
int cellCounter = 0;
cin >> x >> y;
cellNumber = x*y;
cin >> numberOfTunrs;
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
char cellAliveChar;
cin >> cellAliveChar;
if (cellAliveChar == '#')
{
cellTable[cellCounter].isAlive = true;
}
else if (cellAliveChar == '.')
{
cellTable[cellCounter].isAlive = false;
}
cellTable[cellCounter].numberOfAliveNeighbours = 0;
cellTable[cellCounter].group = '#';
cellTable[cellCounter].posX = j;
cellTable[cellCounter].posY = i;
cellCounter++;
}
}
doTurns(x, y);
int result;
result = countGroups();
**cout << result << endl;**
//here is breakpoint
cin >> x;
}
countGroups (idk if it's relevant):
int countGroups()
{
int max = 0;
int current;
int i = 0;
char checkingGroup = 'A';
do
{
current = 0;
for (int j = 0; j < cellNumber; j++)
{
if (cellTable[j].group == checkingGroup + i)
{
current++;
}
}
i++;
if (current > max)
{
max = current;
}
} while (current != 0);
return max;
}
the breakpoint screenshot:
Click to view the screenshot
The problem is cellTable declaration:
int cellNumber;
cell *cellTable = new cell[cellNumber];
Global variables are implicitly initialized with 0 so cellNumber will point to array of 0 size and any attempt to access cellTable items leads to undefined behavior.
It would be better to make all variables local and pass them to functions explicitly. Instead of manually allocating array you should use std::vector, or at least allocate after assigning an appropriate number to cellNumber (after getting x and y values).