Dynamic memory allocation of 2d arrays that are in the struct - c++

I have a struct and I am finding the beginning and end of the lines in an image and in those lines beginning and end of the word, letter etc. (Implementing a basic OCR.)
typedef struct _IMAGE {
int row;
int col;
int max_value;
int **line;
int **space;
int **word;
int **letter;
int **matrix;//holds the image pixels
} IMAGE;
I want to alter my code with dynamically allocated matrices. But since I don't know how many lines and words that will be I don't know the size at the beginning so cannot do simple dynamic allocation. Do you recommend for me to use vectors in this situation? If so how should I use it?

You clarified in a comment that the number of columns in the 2D arrays will be constant, whereas the number of rows can change.
Therefore, you can use 1D vectors and address the elements by mapping the (i, j) indexes to a single index with the formula: k = i * number_of_columns + j.
However, you said that the line array will have only 2 columns, one for the beginning o the line and one for the end. This makes me think that it is more convenient (especially for semantics) to have a Line struct/class with two fields (start, end) and put instances of this struct/class into a simple 1D vector.
When you design an array in which each element has a different meaning depending on its position, and the elements are few, I think it is better to devise an appropriate struct.
Last, since this is C++, you can declare structs in this way:
struct X
{
int a;
// ...
}

No professional image library out there holds image data in a matrix. You should simply do:
struct Image
{
int col;
std::vector<int> matrix;
};
And access the pixels like matrix[x+ col* y]. That will be the quickest, most memory-friendly layout for pixel data. Or use an already existing image struct to avoid the concept of NIH.

Related

Storing objects in 2 dimensional sprite matrix in c++

I want to store a list of tiles (pointers to objects of class "Sprite") in a two dimensional vector.
Currently I'm storing all the sprites of my tilemap in a vector.
std::vector<Sprite*> _tiles;
Now I need to get all the neighbored tiles and I thought it be easier, to store my sprites in a 2d matrix (vector in vector) to do those caluclations.
But I can't figure out how to do that.
Header:
private:
std::vector<std::vector<Sprite*>> matrix;
C++ File:
vectorMatrix::vectorMatrix(int columns, int rows) { }
vectorMatrix::~vectorMatrix() { }
void vectorMatrix::addCellAt(int x, int y, Sprite* sprite) {
std::vector< std::vector<Sprite*> > matrix;
matrix[x][y].push_back(sprite);
}
But I get an error message if I use two index operators.
std::vector< std::vector<Sprite*> > matrix;
This is an empty std::vector of of std::vector, and as others have pointed out, it's no longer the data member matrix.
Since it's empty, it's not possible to do matrix[0] - get the first row, matrix[1] - get the second row... You can however allocate the size of the matrix in your constructor first -- e.g. This will give you a rows*columns matrix
vectorMatrix::vectorMatrix(int columns, int rows)
: matrix(rows, std::vector<Sprite*>(columns))
{
}
And then you can set the xth and yth element to the corresponding Sprite*, and of course x and y should be smaller than rows and columns
matrix[x][y] = sprite;
And don't declare matrix again inside the addCellAt, You can use the data members directly anywhere inside the class.
Why do you think it's a good idea to make your matrix a vector-of-vectors? True, this will "work" in the sense that vec_of_vec_matrix[i][j] will return the right thing, but it's somewhat cumbersome and inefficient.
Instead, consider basing your class on a single vector - of all data, as done in this answer (and probably in many libraries). Element access will be something like (for column-major data):
Sprite*& Matrix::operator()(size_t i, size_t j)
{
return mData[i * num_columns + j];
}
You could even arrange with map[x][y] to work, using a row proxy class.
Three problems:
You declare a local variable matrix inside the function, which shadows the member variable.
If the size of the vectors is not set to include the x and y indexes then you will go out of bounds.
matrix[x][y] is not itself a vector, it's an element that you can assign directly:
matrix[x][y] = sprite;
Remember to consider problem 2 before doing this.

Dynamic allocated 2d array

I have in my class 2 const int variables:
const int m_width;
const int m_height;
In my constructor, I have set the variables and I want to create a 2D array with exactly this size that will be passed by value from the player. I am trying to make a TicTacToe game. I need the input of the user to determine the size of the playing field(in this case the width and height of it). How do I dynamically declare a 2D array in my situation?
It is a common misconception that 2-dimensional matrices should be supported by two-dimensional storage. People often try to use vectors of vectors or other techniques, and this comes at a cost, both performance and code maintainability.
This is not needed. In fact, perfect two-dimensional matrix is a single std::vector, where every row is packed one after each another. Such a vector has a size of of M * N, where M and N are matrix height and width. To access the element at location X, Y, you do v[K], where K is calculated as X * N + Y.
C++ doesn't provide a standard dynamic 2D array container.
What you can do (if you don't want to write your own full implementation) is use an std::vector of std::vectors instead.
It's not exactly the same thing (provides you with an extra degree of freedom: rows can be of different length) but unless you're working in an extremely constrained environment (or need an extremely optimized solution) the extra cost is not big.
Supposing your elements needs to be integers the code to initialize a 2d array can be for example:
std::vector<std::vector<int>> board(rows, std::vector<int>(cols));
PS: A few years ago I wrote a class here to implement a simple 2D array as an answer to an SO question... you can find it here.

c++ Declaring a 2D array as a global variable

I am struggling to figure out how to declare a 2D Array as a global variable so i can use it in all of my methods. So far it is only declared in a single method hence why it cannot be used in other methods.I have figured out how to declare a normal string array by just typing string* array = new string[1] at the start of my code before the methods (i then alter the size of this array later on based of a variable) but i am unsure how to do it with a 2D array:
void WordSearch::ReadSimplePuzzle()
int columns = 9;
int rows = 9;
string **simple2DArray = new string*[columns];
for (int i = 0; i < columns; i++)
simple2DArray[i] = new string[rows];
//code that populates the array too long to post but not relevant.
I then have a method later on where i need to access the simple2DArray but i cannot figure out how to define it at the start of the code any help would be appreciated.
If you columns and rows variables never change, you can do this:
const int columns = 9;
const int rows = 9;
string simple2DArray[columns][rows];
By statically allocating the memory, you now don't have to worry about freeing it.
Since you clarified that the size is not known until run-time, you will not be able to allocate the memory statically. A very simple solution would be:
std::vector<std::vector<std::string>> simple2DArray; // This will have size 0 at start
Then, in your initialization step, just do this:
simple2DArray.resize(rows);
for (auto& row : simple2DArray)
{
row.resize(columns);
}
There are other ways to do this, of course, such as allocating all the memory in one block of size rows*columns and then exposing it as if it were a 2-d matrix but that might be overkill for your purposes.
My suggestion is hide the array behind a functional interface.
std::string const& getElement(size_t m, size_t n);
void setElement(size_t m, size_t n, std::string const& val);
The calling functions have the abstractions of a 2D array but they don't need to know how the it is represented in code.
In the implementation, you have various options:
Use a 1D array. Map the 2D indices to the right index in the 1D array.
Use a std::vector. Still need to map the indices.
Use a 2D array. No mapping of indices needed.
Use a std::vector<std::vector<std::string>>. No mapping of indices needed.
I am struggling to figure out how to declare a 2D Array as a global
variable so i can use it in all of my methods.
As with any global var, you need to declare your pointer in global space:
string **simple2DArray;
and then you can assign to it from inside your method
simple2DArray = new string*[columns];
If you are asking this for making it easier to solve competitive programming problems, then look at the constraints given in the question. For example if the matrix can be an N*N with 1 <= N <= 1000 Then you can globally declare int arr[1000][1000];
Here's some code for a better idea.
//global declarations
int N;
int arr[1000][1000];
int functionA()
{
// some code
}
int functionB()
{
// some code
}
int main()
{
// Get the input of both N and your array arr
// Now you can use them in any where in your code
}

How does the performance of a Multidimensional array compare to an array of objects?

Say I have 3 values:
int age;
int girth;
int length;
Would it be more efficient to store and loop through these values in a multidimensional array OR to declare a class with these 3 member variables and then fill an array with objects of this class?
If you want to interpret every dimension as one of your values, it will be ok for the small array sizes. Despite that, when you will fall out of cache, you will probably experience huge decrease in performance if you want to access first element of the first dimension, then of the second and third dimensions. It is due to memory layout of multi dimensional arrays and CPU caching.
If you'll have it as a struct or all 3 values are interpreted as one dimension of the array, and If you will keep accessing that array in traversal manner (e.g. not jumping around), then you will get probably the best performance possible.
So, it should be like this:
struct entry
{
int age;
int girth;
int length;
}
std::array<entry, /*size*/> entries;

Is it worth to use vector in case of making a map

I have got a class that represents a 2D map with size 40x40.
I read some data from sensors and create this map with marking cells if my sensors found something and I set value of propablity of finding an obstacle. For example when I am find some obstacle in cell [52,22] I add to its value for example to 10 and add to surrounded cells value 5.
So each cell of this map should keep some little value(propably not bigger). So when a cell is marked three times by sensor, its value will be 30 and surronding cells will have 15.
And my question is, is it worth to use casual array or is it better to use vector even I do not sort this cells, dont remove them etc. I just set its value, and read it later?
Update:
Actually I have in my header file:
using cell = uint8_t;
class Grid {
private:
int xSize, ySize;
cell *cells;
public:
//some methods
}
In cpp :
using cell = uint8_t;
Grid::Grid(int xSize, int ySize) : xSize(xSize), ySize(ySize) {
cells = new cell[xSize * ySize];
for (int i = 0; i < xSize; i++) {
for (int j = 0; j < ySize; j++)
cells[x + y * xSize] = 0;
}
}
Grid::~Grid(void) {
delete cells;
}
inline cell* Grid::getCell(int x, int y) const{
return &cells[x + y * xSize];
}
Does it look fine?
I'd use std::array rather than std::vector.
For fixed size arrays you get the benefits of STL containers with the performance of 'naked' arrays.
http://en.cppreference.com/w/cpp/container/array
A static (C-style) array is possible in your case since the size in known at compile-time.
BUT. It may be interesting to have the data on the heap instead of the stack.
If the array is a global variable, it's ugly an bug-prone (avoid that when you can).
If the array is a local variable (let say, in your main() function), then a stack overflow may occur. Well, it's very unlikely for a 40*40 array of tiny things, but I'd prefer have my data on the heap, to keep things safe, clean, and future-proof.
So, IMHO you should definitely go for the vector, it's fast, clean and readable, and you don't have to worry about stack overflow, memory allocation, etc.
About your data. If you know your values are storable on a single byte, go for it !
An uint8_t (same as unsigned char) can store values from 0 to 255. If it's enough, use it.
using cell = uint8_t; // define a nice name for your data type
std::vector<cell> myMap;
size_t size = 40;
myMap.reserve(size*size);
side note: don't use new[]. Well, you can, but it has no advantages over a vector. You will probably only gain headaches handling memory manually.
Some advantages of using a std::vector is that it can be dynamically allocated (flexible size, can be resized during execution, etc) and can be passed/returned from a function. Since you have a fixed size 40x40 and you know you have one element int in every cell, I don't think it matters that much in your case and I would NOT suggest using a class object std::vector to process this simple task.
And here is a possible duplicate.