I am having an issue with accessing 2d array elements.
While creating an object I allocate memory for my array in the constructor.
Once the object is created when I try to access array elements I am getting EXC_BAD_ACCESS.
I checked and when still in constructor I can access array elements.
I don’t know what I am doing wrong.
This is my class where I allocate memory for data array;
class TableData
{
public:
TableData(std::string name, int rows, int columns) : tableName(name), rowCount(rows), columnCount(columns)
{
data = new std::string*[rowCount];
for (int count = 0; count < rowCount; ++count)
data[count] = new std::string[columnCount];
columnID.resize(columnCount);
//Below I did a test where can see that I can access array elements
data[0][0]=“test1111”;
std::string test = data[0][0];
}
~TableData()
{
for (int count = 0; count < rowCount; ++count)
delete[] data[count];
delete[] data;
}
std::string **data;
std::string tableName = "";
const int rowCount;
const int columnCount;
std::vector<std::string> columnID;
};
When I try to fill an array with data I am getting "Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)"
ecuData.tables.push_back(TableData(name, tableRowCount, tableColumnCount));
ecuData.tables[i].data[0][0]=“test2222”; // Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)
“tables” is a vector of TableData objects
Here is a full function:
void Decoder::getTables(std::fstream &fs, std::vector<char> & buffer, SGBDdata &ecuData)
{
const int ptr_offset = 0x84;
int tableOffset = *reinterpret_cast<int32_t*>(&buffer[0] + ptr_offset);
const int tableCountBufferLength = 4;
vector<char> tableCountBuffer;
fs.seekg(tableOffset, fs.beg);
readAndDecryptBytes(fs, tableCountBuffer, tableCountBufferLength);
int tableCount = *reinterpret_cast<int32_t*>(&tableCountBuffer[0] + 0);
for(int i = 0; i < tableCount; ++i) //iterate through tables
{
int tableBufferLength = 0x50;
vector<char> tableBuffer;
readAndDecryptBytes(fs, tableBuffer, tableBufferLength);
string name(tableBuffer.begin(), tableBuffer.begin() + 0x40);
TrimEnd(name);
int tableColumnOffset = *reinterpret_cast<int32_t*>(&tableBuffer[0] + 0x40);
int tableColumnCount = *reinterpret_cast<int32_t*>(&tableBuffer[0] + 0x48);
int tableRowCount = *reinterpret_cast<int32_t*>(&tableBuffer[0] + 0x4C);
//**This is where I am creating new “TableData” object and putting it into vector<TableData>**
ecuData.tables.push_back(TableData(name, tableRowCount, tableColumnCount));
long savedPos = fs.tellg();
fs.seekg(tableColumnOffset, fs.beg);
//Load column names
for(int j = 0; j < tableColumnCount; ++j)
{
int tableItemBufferLength = 1024;
vector<char> tableItemBuffer;
for(int k = 0; k < tableItemBufferLength; ++k)
{
readAndDecryptBytes(fs, tableItemBuffer, 1);
if (tableItemBuffer[k] == 0)
break;
}
ecuData.tables[i].columnID.push_back(string(tableItemBuffer.begin(), tableItemBuffer.end() - 1));
}
for(int j = 0; j < tableRowCount; ++j)
{
for (int k = 0; k < tableColumnCount; ++k)
{
int tableItemBufferLength = 1024;
vector<char> tableItemBuffer;
for (int l = 0; l < tableItemBufferLength; ++l)
{
readAndDecryptBytes(fs, tableItemBuffer, 1);
if (tableItemBuffer[l] == 0)
break;
}
string s(tableItemBuffer.begin(), tableItemBuffer.end() - 1);
ecuData.tables[i].data[j][k] = s; //**This is where I get my fault**
}
}
fs.seekg(savedPos, fs.beg);
}
}
Here is SGBDdata class. The ecuData object of this class contains a vector data
class SGBDdata
{
public:
std::string sgbdPath;
std::string ecuName;
std::vector<JobData> jobs;
std::vector<TableData> tables;
};
lose all the new, delete, and pointer magic. and use a vector of vectors?
// Example program
#include <iostream>
#include <string>
#include <vector>
class TableData
{
public:
TableData(std::string name, int rows, int columns) : tableName(name), rowCount(rows), columnCount(columns)
{
data.resize(columnCount);
for( int i = 0; i < columnCount; i++)
{
data[i].resize(rowCount);
}
columnID.resize(columnCount);
//Below I did a test where can see that I can access array elements
data[0][0]="test1111";
std::string test = data[0][0];
}
~TableData()
{
}
std::vector<std::vector<std::string>> data;
std::string tableName = "";
const int rowCount;
const int columnCount;
std::vector<std::string> columnID;
};
int main()
{
TableData test = TableData( "me", 3,3);
test.data[0][0]="test2222";
std::cout<<test.data[0][0];
}
I have managed to get the code working. As #dratenik mentioned the problem was related to shallow copy which was taking place in default copy constructor. To get it fixed I have added a move constructor to TableData class.
class TableData
{
public:
TableData(std::string name, int rows, int columns) : tableName(name), rowCount(rows), columnCount(columns)
{
data = new std::string*[rowCount];
for (int count = 0; count < rowCount; ++count)
data[count] = new std::string[columnCount];
columnID.resize(columnCount);
}
TableData(TableData&& t) : rowCount(t.rowCount), columnCount(t.columnCount)
{
tableName=t.tableName;
data = new std::string*[rowCount];
for (int count = 0; count < rowCount; ++count)
data[count] = new std::string[columnCount];
for (int r_count = 0; r_count < rowCount; ++r_count)
for (int c_count = 0; c_count < columnCount; ++c_count)
data[r_count][c_count] = t.data[r_count][c_count];
}
~TableData()
{
for (int count = 0; count < rowCount; ++count)
delete[] data[count];
delete[] data;
}
std::string **data;
std::string tableName = "";
const int rowCount;
const int columnCount;
std::vector<std::string> columnID;
};
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) {. . .}
I need to read a txt file and store it into a matrix (we suppose that it'a a 2x2 matrix). I have a problem with the code below (I semplified it to be more cleat):
#include<stdexcept>
#include<string>
#include<fstream>
using namespace std;
class A{
private:
int **m;
void allocate_mem(int ***ptr){
*ptr = new int *[2];
(*ptr)[0] = new int[2*2];
for(unsigned i = 1; i < 2; i++)
(*ptr)[i] = (*ptr)[0] + i*2;
}
void read_file(string file_input){
ifstream fin(file_input.c_str());
allocate_mem(&m);
char a;
for(unsigned i = 0; i < 2; i++) {
for (unsigned j = 0; j < 2; j++) {
a = fin.get();
if(a=="X"){
//ISO C++ forbids comparison between pointer and integer [-fpermissive]
m[i][j] = 1;
}else{
m[i][j] = 0;
}
}
}
fin.close();
}
public:
A(){
throw logic_error("Error!");
}
A(string file_name){
read_file(file_name);
}
~A(){
delete[] m[0];
delete[] m;
}
};
input.txt
XX
X
I want to store a 2x2 matrix whose elemets are:
11
01
The solution is simple: Write C++ instead of C
Use standard containers instead of manual memory management.
Also, if you know the size of the data at compile-time, why do you use dynamic memory?
int m[2][2];
void read_file(const std::string& file_input) {
ifstream fin(file_input.c_str());
char a;
if( !fin ) throw;
for (std::size_t i = 0; i < 2; i++) {
for (std::size_t j = 0; j < 2; j++) {
a = fin.get();
if (a == 'X') { // '' is for characters, "" for strings. Thats why the compiler
m[i][j] = 1;// warns you (You are comparing the char[], which is decayed to
} else { // char*, with the integer value of the char variable)
m[i][j] = 0;
}
}
}
//Close not needed (RAII)
}