How To Implement Linear Arrays in C++?

Hello Professionals,

Good day. I just realized that it's better to implement arrays in C++ such as shown below:

index = [(i*height*depth) + (j*depth) + k]

However, I am still new to this implementation, and I wanted to ask your advice how will I implement this?

For example, if I have a set of values:

1 2 3
4 5 6
7 8 9

Wherein:
1 is at [0][0] index
2 is at [0][1] index
3 is at [0][2] index
4 is at [1][0] index
5 is at [1][1] index
6 is at [1][2] index
7 is at [2][0] index
8 is at [2][1] index
9 is at [2][2] index

How can I effectively utilize the [(i*height*depth) + (j*depth) + k] to completely access the values above?
Using a multidimensional array:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

int main()
{
	const int height = 3;
	const int width  = 3;
	
	int m[height][width] = 
	{
		{1, 2, 3},
		{4, 5, 6},
		{7, 8, 9}
	};
	
	for (int y = 0; y < height; ++y)
	{
		for (int x = 0; x < width; ++x)
		{
			std::cout << m[y][x] << ' '; 
		}
		std::cout << '\n';
	}
}

Using a linear array:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

int main()
{
	const int height = 3;
	const int width  = 3;
	
	int m[height * width] = 
	{
		1, 2, 3,
		4, 5, 6,
		7, 8, 9
	};
	
	for (int y = 0; y < height; ++y)
	{
		for (int x = 0; x < width; ++x)
		{
			std::cout << m[y * width + x] << ' '; 
		}
		std::cout << '\n';
	}
}
I highly recommend a thin class that has the dimensions and wraps this in an inline function that does the math for you so you can just have
thing.set(row,col, value);
I don't know if there is a way to overload an operator to make this cleaner. Probably.

note that for arrays, it does not matter:

x[10][20] IS a solid block of bytes, you can collapse it to 1d with pointer magic (type * oned = & x[0][0]).

the issue is dynamic arrays and vectors that get a block for each row.

type ** ugly;
ugly = new type*[size]; //one block of memory.
for(i=... size)
ugly[i] = new type[size2];//multiple blocks of memory in random places in ram.

this is fragmented and causes page faults and problems and can't be directly iterated to touch all items and is a performance hit for large data.

thing.set(row,col, value);
I don't know if there is a way to overload an operator to make this cleaner. Probably.

You can do it with a helper class. think.operator[] returns an instance of the helper. Helper.operator[] returns the data that you really want. This lets you say thing[row][col]. Here's a simplified example.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>

class TwoDArray {
public:
    TwoDArray(size_t r, size_t c) :
	rows(r), cols(c)
    {
	data = new int[rows*cols]{};
    }
    ~ TwoDArray() {
	delete[] data;
    }
    class TwoDIdx {
    public:
	TwoDIdx(TwoDArray &arr, size_t r) :
	    array(arr), row(r) {}
	TwoDArray &array;
	size_t row;
	int &operator [] (size_t col) {
	    return array.data[col*row];
	}
    };
    TwoDIdx operator[](size_t idx) {
	return TwoDIdx(*this, idx);
    }

private:
    size_t rows, cols;
    int *data;
};


    
int
main()
{
    TwoDArray arr(10,15);
    arr[3][4] = 7;
    
    for (size_t c=0; c<15; ++c) {
	std::cout << arr[3][c] << ' ';
    }
    std::cout << '\n';
    return 0;
}
Nice example, TY. I should have known that, but was mentally hung up thinking about the syntax and not working the actual problem.


Thank you very much guys for sharing your thoughts. God bless you all! :)
Topic archived. No new replies allowed.