I am currently creating a program that simulates a Galton board in C++. I understand how to create a pointer, create an array of pointers, and point each one at another array of ints. My problem is occuring when i try to descruct my pointer array, its telling me:
"Debug Error!
HEAP CORRUPTION DETECTED: after Normal block (#927) at 0x0115E978.
CRT detected that the application wrote to memory after end of heap buffer."
I've been banging my head against the wall with this one, as it seems all the examples I can find online have this exact approach. I even rewrote my program into a class to make it more simple. The program runs and does exactly what it's supposed to until the ob1 starts to descruct, which is when the program pukes. I'm stuck.
Here is my code:
#include <iostream>
#include <string>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;
class foo
{
public:
foo();
foo(int);
~foo();
void allocateSpace();
void runGame();
void printResults();
private:
int bins;
int** p;
};
foo::foo()
{
this->bins = 0;
}
foo::foo(int bins)
{
this->bins = bins;
this->p = new int*[bins]; //setting p to array of pointers
}
foo::~foo()
{
for (int i = 0; i < bins; i++)
{
delete[] this->p[i];
}
delete[] p;
}
void foo::allocateSpace()
{
for (int i = 0; i < bins; i++)
{
this->p[i] = new int[i]; //creatung an int array of size i at each pointer array cell
for (int j = 0; j <= i; j++)
{
this->p[i][j] = 0;
}
}
}
void foo::runGame()
{
const int numOfRuns = 1000;
for (int i = 0; i < numOfRuns; i++)
{
this->p[0][0]++; //each ball hits the first peg, so always increment it before anything else
int j = 0; //setting j = 0 sets it to the left
for (int i = 1; i < bins; i++)
{
int rando = rand() % 2;
if (rando == 1) //move right
{
j++;
}
this->p[i][j]++;
}
}
}
void foo::printResults()
{
for (int i = 0; i < bins; i++)
{
for (int j = 0; j <= i; j++)
{
cout << setw(5) << this->p[i][j];
}
cout << endl;
}
}
int main()
{
srand(time(0));
int numOfBins;
cout << "Enter the number of bins: ";
cin >> numOfBins;
cout << endl;
foo ob1(numOfBins);
for (int i = 0; i < 50; i++)
{
ob1.allocateSpace();
ob1.runGame();
ob1.printResults();
}
system("pause");
return 0;
}
Any help would be much appreciated.
In allocateSpace, you write beyond the allocated object. This corrupts your heap.
this->p[i] = new int[i];
for (int j = 0; j <= i; j++)
{
this->p[i][j] = 0;
}
printResults has a similar problem: You read beyond the allocated object.
Then, in runGame, you attempt to increment a 0 sized object.
this->p[0][0]++;
The fix:
It seems you need to increase your allocation by 1.
this->p[i] = new int[i+1];
This will avoid the heap corruption issue. You still have a memory leak issue, because you allocate new memory on top of your existing memory on each iteration in main().
Your code would be safer if you adopted the use of vector<> instead of managing dynamically allocated arrays.
Related
could you help me with little problem?
I have following class;
class Link
{
private:
Demand *demand_[NUMBER_OF_CORES][NUMBER_OF_SLICES];
public:
Link()
{
for (int i = 0; i < NUMBER_OF_CORES; i++)
{
for (int j = 0; j < NUMBER_OF_SLICES; j++)
{
demand_[i][j] = NULL;
}
}
}
int virtualPut();
}
There will be problem with demand_ array. In the constructor everything is fine, after initialization I can use if (demand_[i][j] == NULL).
Problem starts in virtualPut()
int Link::virtualPut()
{
for (int i = 0; i < NUMBER_OF_CORES; i++)
{
for (int j = 0; j < NUMBER_OF_SLICES; j++)
{
std::cout << "We're in " << i << " " << j << " \n" << std::flush;
if (demand_[i][j] == NULL) //SEGMENTATION FAULT
{
std::cout << "EMPTY\n";
}
}
}
}
And also - if I call virtualPut() in constructor (just for test) it works fine.
But outside Link class I use.
void someFunction(Link *tab, int links)
{
tab = new Link[links];
tab[0].virtualPut(); //also just for test
}
What could be a problem here? I know that I can use vector, but that won't help me understand this memory problem.
One more thing - Dr. Memory says:
UNADDRESSABLE ACCESS: reading 0x0000000000000009-0x0000000000000011 8 byte(s)
But why?
EDIT!
Problem solved in comments, thank you
The code you show us is okay. I ran it on my side with huge values, and there is no Segfault.
You declared a "Demand* array of array" in your Link class, and this is a valid declaration, the memory should be allocated.
What I do suspect is that NUMBER_OF_CORES and/or NUMBER_OF_SLICES doesn't have the same value in the code where you defines the Link class and in the code where you defined the virtualPut method.
Something like :
#define NUMBER_OF_CORES 10
#define NUMBER_OF_SLICES 10
class Link
{
private:
Demand *demand_[NUMBER_OF_CORES][NUMBER_OF_SLICES];
...
}
and
#define NUMBER_OF_CORES 5000
#define NUMBER_OF_SLICES 5000
int Link::virtualPut()
{
for (int i = 0; i < NUMBER_OF_CORES; i++)
{
for (int j = 0; j < NUMBER_OF_SLICES; j++)
{
// here you will have buffer overflow
...
}
What I would do :
use std::vector
probably use a single entry array, and wrap it up
don't use #define, it's messy
don't use arrays, it generates buffer overflow
That would be something like this :
class Link
{
private:
std::vector<Demand*> demand_;
const int NUMBER_OF_CORES = 10;
const int NUMBER_OF_SLICES = 50;
private:
int getIdx(int i, int j)
{
return i*NUMBER_OF_SLICES + j;
}
public:
Link()
{
demand_.resize(NUMBER_OF_CORES * NUMBER_OF_SLICES);
for (int i = 0; i < NUMBER_OF_CORES; i++)
{
for (int j = 0; j < NUMBER_OF_SLICES; j++)
{
demand_[getIdx(i,j)] = NULL;
}
}
}
int virtualPut();
};
Note : additionaly, you showed us a virtualPut() that should return an int but doesn't.
Good evening, folks.
I'm currently experiencing difficulties with extracting pair numbers from an array. I have the following code:
#include <iostream>
using namespace std;
int *paire(int *d, int length) {
int counter = 0;
int position = 0;
for (int i=0; i<length; i++) {
if (d[i] % 2 ==0)
counter++;
}
int *k = new int[counter];
for (int i=0; i<length; i++) {
if (d[i] % 2 ==0) {
k[position] = d[i];
position++;
}
}
return k;
}
int main() {
int b[8] = {1,2,3,4,5,6,7,8};
int *array1 = paire(b,8);
for (int i=0; i<5; i++) { // how can I point here to the counter in paire() ?
cout<<array1[i];
}
delete[] array1;
return 0;
}
So I think I've got it right with initializing the new array in function paire, but I'm having difficulties to iterate through the array.
P.S. I'm first year in university, so I would really be thankful if you can keep the same simplicity in the answers. Thanks in advance!
It appears that you need to return 2 separate values: the number of even numbers in the array b, and the address of the newly allocated memory that is storing exclusively those even numbers.
Since you can not return multiple variables, one solution that does minimal modification to your code would be as follows.
int *paire(int *d, int length, int& counter) {
counter = 0;
// rest of your function remains unchanged
// ...
}
int main() {
int b[8] = {1,2,3,4,5,6,7,8};
int evenNumbers;
int *array1 = paire(b,8, evenNumbers);
for (int i=0; i<evenNumbers; i++) {
cout<<array1[i];
}
delete [] array1;
return 0;
}
Alternatively, you can return the value in counter and send the reference to the int* variable as an argument to paire function. Or, you can declare paire to have return type void and use references to pass back both the values.
You can further simplify your function by allocating to that of the length and returning the counter by an output parameter.
#include <iostream>
using namespace std;
int *paire(int *d, int length, int &counter) {
counter = 0;
int *k = new int[length]; // allocate for the maximum memory
for (int i = 0; i < length; ++i) {
if (d[i] % 2 == 0) {
k[counter++] = d[i];
}
}
return k;
}
int main() {
int b[8] = {1,2,3,4,5,6,7,8};
int counter = 0;
int *array1 = paire(b,8, counter);
for (int i=0; i<counter; i++) { // how can I point here to the counter in paire() ?
cout<<array1[i] << " ";
}
delete [] array1;
return 0;
}
But please note that as others have already pointed out this method is quite error prone in the sense that it leaves the responsibility to the client to delete the internal memory used by paire function.
I want to declare two dimensional array with variable size.
I wrote the following code but something goes wrong!
int **p2DArray;
p2DArray = new int*[target_counter_new];
for (int i = 0; i < target_counter_new; ++i)
{
p2DArray[i] = new int[target_counter_old];
}
for(int i_oghli=0;i_oghli<target_counter_new;i_oghli++)
for(int j_oghli=0;j_oghli<target_counter_old;j_oghli++)
{
p2DArray[i_oghli][j_oghli]=i_oghli+10;
cout<<p2DArray[i_oghli][j_oghli];
}
what is problem here ?
#include <iostream>
using namespace std;
const int target_counter_new = 4;
const int target_counter_old = 4;
int main() {
int **p2DArray;
p2DArray = new int*[target_counter_new];
for (int i = 0; i < target_counter_new; ++i) {
p2DArray[i] = new int[target_counter_old];
}
for(int i_oghli=0;i_oghli<target_counter_new;i_oghli++) {
for(int j_oghli=0;j_oghli<target_counter_old;j_oghli++) {
p2DArray[i_oghli][j_oghli]=i_oghli+10;
cout<<p2DArray[i_oghli][j_oghli] << " ";
}
cout << endl;
}
// don't forget to delete the array
for (int i = 0 ; i < target_counter_new; ++i) {
delete [] p2DArray[i];
}
delete [] p2DArray;
return 0;
}
Check here : code
There doesn't appear to be any problem.
I am making conway's game of life. I have two classes, one for the plane of cells, and another for the cells. The cells are like a 2d linked list with 4 pointers per cell pointing to the vertical and horizontal neighbors. When trying to access any of the cell pointers to other cells, or the alive member the program crashes.
my code
//game.h
#ifndef GAME_H_
#define GAME_H_
#include <iostream>
class cell{
public:
bool alive;
cell* top;
cell* bot;
cell* lef;
cell* rig;
cell(){
alive = false;
top = bot = lef = rig = nullptr;
}
cell* link(char);
int alive_neighbors();
void link_right(cell*);
void link_down(cell*);
void refresh_cell();
};
class field{
public:
int size;
cell * origin;
bool ** new_state;
cell *** fi;
field(int a);
~field();
};
#endif
and
//game.cpp
#include <iostream>
#include "game.h"
int cell::alive_neighbors(){
int num = 0;
(this->top)?((this->top->alive)?(++num):(num)||((this->top->rig)?((this->top->rig->alive)?(num++):(num)):(num))):(num);
(this->bot)?((this->bot->alive)?(++num):(num)||((this->bot->lef)?((this->bot->lef->alive)?(num++):(num)):(num))):(num);
(this->rig)?((this->rig->alive)?(++num):(num)||((this->rig->bot)?((this->rig->bot->alive)?(num++):(num)):(num))):(num);
(this->lef)?((this->lef->alive)?(++num):(num)||((this->lef->bot)?((this->lef->bot->alive)?(num++):(num)):(num))):(num);
return num;
}
void cell::link_right(cell* linkee){
this->rig = linkee;
linkee->lef = this;
}
void cell::link_down(cell* linkee){
this->bot = linkee;
linkee->top = this;
}
field::field(int a){
size = a;
for (int i= 0; i < size; i++){
fi[i] = new cell*[size];
for (int j = 0; j < size; j++){
fi[i][j] = new cell;
}
}
for (int i = 0; i < size; i++){
for (int j = 0; j < size -1; j++){
this->fi[i][j]->link_right(this->fi[i][j+1]);
this->fi[j][i]->link_down(this->fi[j+1][i]);
}
}
origin = fi[0][0]
}
field::~field(){
for (int i = size -1; i >= 0; i--){
for (int j = size -1;j >= 0; j--){
delete fi[i][j];
}
delete fi[i];
}
}
Error:
#include "game.h"
int main(){
field game(10);
std::cout << game.origin->alive << std::endl; //compiles but crashes :(
std::cout << game.origin->rig << std::endl; //also compiles and crashes without giving adress.
std::cout << game.fi[0][0]->alive; //even directly accessing the cell compiles and crashes.
}
The problem was with game.cpp try this code
//game.cpp
#include <iostream>
#include "stackoverflow.hpp"
int cell::alive_neighbors(){
int num = 0;
(this->top)?((this->top->alive)?(++num):(num)||((this->top->rig)?((this->top->rig->alive)?(num++):(num)):(num))):(num);
(this->bot)?((this->bot->alive)?(++num):(num)||((this->bot->lef)?((this->bot->lef->alive)?(num++):(num)):(num))):(num);
(this->rig)?((this->rig->alive)?(++num):(num)||((this->rig->bot)?((this->rig->bot->alive)?(num++):(num)):(num))):(num);
(this->lef)?((this->lef->alive)?(++num):(num)||((this->lef->bot)?((this->lef->bot->alive)?(num++):(num)):(num))):(num);
return num;
}
void cell::link_right(cell* linkee){
this->rig = linkee;
linkee->lef = this;
}
void cell::link_down(cell* linkee){
this->bot = linkee;
linkee->top = this;
}
field::field(int a){
size = a;
fi = new cell**[size];
for (int i= 0; i < size; i++){
fi[i] = new cell*[size];
for (int j = 0; j < size; j++){
fi[i][j] = new cell;
}
}
for (int i = 0; i < size; i++){
for (int j = 0; j < size -1; j++){
this->fi[i][j]->link_right(this->fi[i][j+1]);
this->fi[j][i]->link_down(this->fi[j+1][i]);
}
}
origin = fi[0][0];
}
field::~field(){
for (int i = size -1; i >= 0; i--){
for (int j = size -1;j >= 0; j--){
delete fi[i][j];
}
delete fi[i];
}
}
I do not understand why people here tend to get annoyed because the ones asking questions are not coding with the "correct" style. We all need to make mistakes and learn from them. On that note in the future when you work on another C++ project. Try using the STL containers, they will be refreshingly simple and efficient. You'll love them.
Also think of n-dimensional arrays this way. Use one * for every dimension. So an int* arr is a 1-D array and an int** arr is a 2-D array. You can switch to a cell** here since you want a 2-D array :)
I have a class named Test and I'd like to create empty 2D array that will hold instances of that class and than add them later one by one using constructor that accepts parameters.
Basically, I'd just like to reserve memory that I will fill in later with objects. It needs to bee on a heap since I will have class that will generate 2D arrays of different sizes.
This was my first approach but it doesn't really work since Test class doesn't have default constructor:
Test** arr;
arr = new Test*[10];
for (int i = 0; i < 10; i++)
arr[i] = new Test[10];
[EDIT]
Here is my full test code. All in all, I'm getting wrong values out, it should be numbers from 0 to 99:
#include <iostream>
using namespace std;
class Test {
private:
short number;
public:
Test(short n) {
this->number = n;
}
short getNumber() {
return number;
}
};
int main() {
Test** arr;
arr = new Test*[10*10];
for (int i = 0; i < 100; i++)
arr[i] = new Test(i);
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++)
cout << arr[i][j].getNumber() << " ";
cout << endl;
}
}
Maybe try using a default constructor with default parameters?
Test(int i = 0) {. . .}