Multidimensional Character Array - c++

How do you initialize and Uninitialize a multidimensional character array in C++?

Read the FAQ -- you'll find everything you need there!
Creation:
Statically allocated:
char mda[ dim1_size ][ dim2_size ]...[ dimn_size ];
Dynamically allocated: Nested new[] calls.
Initialization:
Nested for loops; as many for as your dimensions.
Unitialization: Do you mean Destruction?
Statically allocated: The compiler does this when the stack frame is unwound (or for global variables -- when the program stops running).
Dynamically allocated:
Using nested delete[].

I suggest you use the Boost.Multi_Array library.
The dimension of the array has to be provided at compile-time, but the sizes are only used at runtime.
That means that you have the advantages of dynamic allocation without the pain of having to deal with memory issues.
Here goes the example from the Boost documentation.
int
main () {
// Create a 3D array that is 3 x 4 x 2
typedef boost::multi_array<double, 3> array_type;
typedef array_type::index index;
array_type A(boost::extents[3][4][2]);
// Assign values to the elements
int values = 0;
for(index i = 0; i != 3; ++i)
for(index j = 0; j != 4; ++j)
for(index k = 0; k != 2; ++k)
A[i][j][k] = values++;
// Verify values
int verify = 0;
for(index i = 0; i != 3; ++i)
for(index j = 0; j != 4; ++j)
for(index k = 0; k != 2; ++k)
assert(A[i][j][k] == verify++);
return 0;
}

This is interesting, and this requires a serious look.
The answer given by roo is a widely used one, but I like his observation - just because it compiles doesn't mean it works
I would think a better solution would be to allocate a contigious block of memory (rows * cols) long and then treat it as a 2D array?

you can initialize a multidimensional array like this:
int grid[2][3] = {1, 3, 5, 2, 4, 6};
in that case the seperate values would be:
grid[0, 0]: 1
grid[0, 1]: 3
grid[0, 2]: 5
grid[1, 0]: 2
grid[1, 1]: 4
grid[1, 2]: 6

A quick snippet - it compiles in g++.
int rows = 10;
int cols = 10;
char** array = new char*[rows];
for( int i = 0; i < cols; ++i ) {
array[i] = new char[cols];
}
//do stuff with array
for( int i = 0; i < cols; ++i ) {
delete array[i];
}
delete array;

I learned it with a tic tac toe board
const int ROW = 3;
const int COLUMN = 3;
char board [ROW] [COLUMN] = {{'O', 'X', 'O'},
{'X', 'X', 'X'},
{'X', 'O', 'X'}};
I hope this helped.

Related

I am having a bad access issue

I am trying to create a merge function for two array structures in c++ but am coming up with a bad access error that I don't know how to solve. The error comes up when I am trying to swap the element in the smaller array into the larger, merged array. The code doesn't even go through a single iteration. All three of i, j, and k remain at 0. Any help would be greatly appreciated! Here is the code:
struct Array
{
int *A;
int size;
int length;
};
void display(Array arr){
for (int i = 0; i < arr.length; i++)
std::cout << arr.A[i] << std::endl;
}
Array merge(Array arr1, Array arr2){
Array arr3;
arr3.length = arr1.length + arr2.length;
arr3.size = arr1.length + arr2.length;
int i = 0, j =0, k =0;
while(i <arr1.length && j < arr2.length){
if (arr1.A[i] < arr2.A[j])
{
arr3.A[k] = arr1.A[i]; //(The error is displayed here: Thread 1: EXC_BAD_ACCESS (code=1, address=0x28))
k++;
i++;
}
else if (arr2.A[j] < arr1.A[i])
{
arr3.A[k] = arr2.A[j];
k++;
j++;
}
}
for (; i< arr1.length; i++)
{
arr3.A[k]=arr1.A[i];
k++;
}
for (; i< arr2.length; j++)
{
arr3.A[k]=arr2.A[j];
k++;
}
return arr3;
}
int main() {
Array arr1;
arr1.size = 10;
arr1.length = 5;
arr1.A = new int[arr1.size];
arr1.A[0]= 2;
arr1.A[1]= 6;
arr1.A[2]= 10;
arr1.A[3]= 15;
arr1.A[4]= 25;
Array arr2;
arr2.size = 10;
arr2.length = 5;
arr2.A = new int[arr2.size];
arr2.A[0]= 3;
arr2.A[1]= 4;
arr2.A[2]= 7;
arr2.A[3]= 18;
arr2.A[4]= 20;
Array arr3 = merge(arr1, arr2);
display(arr3);
return 0;
}
Your Array arr3 does not allocate any memory for its int *A field. It's natural that it would not work.
Anyway, your implementation of Array is very poor. Don't reimplement arrays unless you have a good reason; use std::vector instead.
If you really need to implement an Array on your own, then learn about encapsulation, make a class with a constructor, and allocate/delete your data (*A) field properly. Remember, using pointers and heap memory without understanding them is a recipe for disaster.
Easy: arr3.A is not initialized. It's a pointer. What does it point to?
Suggestion: learn about dynamic memory allocation.

How to Intialise on double pointer char array like below?

I'm searching to initialize data of char type like below. but I'm not sure on how to do this
char* data[ ][ ] = {
{"", "index1", "clock1", "Rate1"},
{"", "index2", "clock2", "Rate2"},
{"", "index3", "clock3", "Rate3"},
{"", "index4", "clock4", "Rate4"}
}
so that when I want to assign data of above table to other variables like below
for( int i = 0; i < 6; i++)
{
char k[][];
for(int j = 0; j < 6; j++ )
{
k[i][j] = data[i][j];
}
}
and my expected output is like this
k[i][1] = "index1", k[i][2] = "clock1", k[i][3] = "Rate1"
k[i+1][1] = "index2", k[i+1][2] = "clock2", k[i+1][3] = "Rate2" etc.,
How could I initialize the variable data like above to get the values like mentioned in output?
A couple things to note in the k assignment loop. You are looping 0-6 when the array bounds defined in data are 0-3 (4 elements). You initialized k within your for loop. k will need bounds because it is not being initialized. Remember, arrays in C are of a fixed size. Here is the code I'm referring to:
for( int i = 0; i < 6; i++)
{
char k[][]; /* Re-initialize here? */
for(int j = 0; j < 6; j++ )
{
k[i][j] = data[i][j];
}
}
k will need to be initialized with bounds like this:
char* k[4][4];
Also, your assignment of data is not doing what you think it is. You want to initialize it like this:
char* data[4][4] = {
{{""}, {"index1"}, {"clock1"}, {"Rate1"}},
{{""}, {"index2"}, {"clock2"}, {"Rate2"}},
{{""}, {"index3"}, {"clock3"}, {"Rate3"}},
{{""}, {"index4"}, {"clock4"}, {"Rate4"}}
};
In reality though, this also is not going to be very helpful because, as I said above, arrays are of fixed size. Elements data[0][x] are all single element arrays of char. They will serve no purpose. I think you want to assign different strings to them. Assigning/accessing data[0][x][y] where y is greater than 0 will be undefined behavior. It looks like what you really need here is variable length strings. Since you tagged this question with C++, an easy C++ solution would be to use std::string here. If you really need totally variable length strings in C, you will need to use dynamic memory allocation. For a more simple approach, it would be better to assign data with a fixed string size. Later, if you want to assign different strings, you will want to use strcpy.
Below is a solution for you. I used 20 as the fixed string size. You may want more space.
#include<stdio.h>
int main(int argc, char** argv)
{
char data[4][4][20] = {
{{""}, {"index1"}, {"clock1"}, {"Rate1"}},
{{""}, {"index2"}, {"clock2"}, {"Rate2"}},
{{""}, {"index3"}, {"clock3"}, {"Rate3"}},
{{""}, {"index4"}, {"clock4"}, {"Rate4"}}
};
int i;
int j;
char* k[4][4];
for(i = 0; i < 4; i++)
for(j = 0; j < 4; j++ )
k[i][j] = data[i][j];
for (i = 0; i < 4; ++i)
for(j = 0; j < 4; ++j)
printf("%s\n", k[i][j]);
}

Adding element from for loop to an array

I want to create an array with the values from 0 to 4000 by increments of 100 and add those to an array.
I don't have much of as to how to do it.
int wave[] = {};
for(int i = 0; i < 4000; i = i + 100){
//add to wave[] i
}
Any help would be appreciated
Since you can use C++, the default option for storing an array of integers is std::vector:
std::vector<int> wave;
for (int i = 0; i <= 4000; i += 100)
wave.push_back(i);
If you want to have a C array as the result (e.g. for compatibility with other code that uses such arrays), because you know the final size of your array in advance, you better mention the size in the array definition:
int wave[41];
int index = 0;
for (int value = 0; value <= 4000; value += 100)
wave[index++] = value;
If you didn't know the final size, and for some reason didn't want to use std::vector, you'd have to use dynamically-allocated arrays (with malloc or new[]).
int main()
{
int wave[4096/100 + 1];
for(int i = 0, j=0; i < 4096; i = i + 100, j++)
wave[j]= i;
}

Initialize multidimensional array with zeros

In C++ you can initialize a one dimensional array with 0 with a code like this:
int myarray[100] = {0};
Is there a similar way for multidimensional arrays? Or am i forced to initialize it manually with for loops?
You do it exactly the same way
int marr[10][10] = {0};
Edit:
This is a C solution. For a C++ solution you can go for:
int marr[10][10] = {};
These 2 solutions do not work for arrays that have size defined via variables. e.g.:
int i, j = 10;
int marr[i][j];
To initialize such an array in C++ use std::fill.
A multidimensional array is an array of arrays.
The same general array initialization syntax applies.
By the way you can just write {}, no need to put an explicit 0 in there.
use vector instead of array it will give you more flexibility in declaration and in any other operation
vector<vector<int> > myarray(rows,vector<int>(columns, initial_value));
you can access them same as you access array,
and if u still want to use array then use std::fill
You could use std::memset to initialize all the elements of a 2D array like this:
int arr[100][100]
memset( arr, 0, sizeof(arr) )
Even if you have defined the size via variables this can be used:
int i=100, j=100;
int arr[i][j]
memset( arr, 0, sizeof(arr) )
This way all the elements of arr will be set to 0.
Using 2 vector containers:
std::vector<std::vector<int>> output(m, std::vector<int>(n, 0));
This way one can declare a 2D vector output of size (m*n) with all elements of the vector initialized to 0.
For "proper" multi-dimensional arrays (think numpy ndarray), there are several libraries available, for example Boost Multiarray. To quote the example:
#include "boost/multi_array.hpp"
#include <cassert>
int
main () {
// Create a 3D array that is 3 x 4 x 2
typedef boost::multi_array<double, 3> array_type;
typedef array_type::index index;
array_type A(boost::extents[3][4][2]);
// Assign values to the elements
int values = 0;
for(index i = 0; i != 3; ++i)
for(index j = 0; j != 4; ++j)
for(index k = 0; k != 2; ++k)
A[i][j][k] = values++;
// Verify values
int verify = 0;
for(index i = 0; i != 3; ++i)
for(index j = 0; j != 4; ++j)
for(index k = 0; k != 2; ++k)
assert(A[i][j][k] == verify++);
return 0;
}
See also: High-performance C++ multi-dimensional arrays
In C++, simply you can also do this way:-
int x = 10, y= 10; int matrix[x][y] = {};
and then the 2d-array will be initialized with all zeroes.

tr1::array in C++ deleting all elements

how to delete all elements of a std::tr1::array?
For example I have defined the following array.
std::tr1::array <int, 5> a = { 1, 2, 3, 4, 5}
Just like in vectors I am looking for a method such as a.clear() or a.erase() but couldn't find one for arrays.
Thank you
arrays are static size, you can neither add nor remove elements, that's what vector is for.
Once defined, the size of an array cannot be modified.
Arrays have a fixed size. You can, however, keep track of the number of elements you use in the array, for a fixed-maximum-sized-vector:
array<int,5> arr;
int number_of_elements = 0;
for ( int i = 0; i < 4; ++i ) {
// arr.push_back(i)
arr[number_of_elements] = i;
number_of_elements++;
}
// arr.erase( arr.begin() + 2 )
for ( int i = 2; i < number_of_elements-1; ++i )
arr[i] = arr[i+1];
number_of_elements--;
// arr.clear()
number_of_elements = 0;
you can delete specific index information if want!
for(int i=0;i<n;i++) //for deletion
{
if(arr[i]==_delete)
{
arr[i]=arr[i+1];
--n;
}
}