Initializing a 2D Array C++ - c++

My goal is to read in a file at the command line, which is to be an adjacency matrix representation of a directed graph, and store the values in a 2D array. My plan is to read the number of integers on a line and use that as the size for my array(i.e. a 5 line input, with 5 integers per line would mean i would create a 5 x 5 array). However, to initialize an array, a constant value is needed, and counting the integers per line and storing it in a variable to use as my size parameter, does not allow me to create the array.
Sample input:
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
Code:
#include <iostream>
#include <sstream>
#include <fstream>
using namespace std;
int main(int argc, char **argv)
{
string currentLine;
int i, m = 0;
int count;
ifstream input(argv[1]);
int storage[10000];
printf("Original matrix: \n" );
if(input.is_open())
{
while(getline(input, currentLine))
{
istringstream iss(currentLine);
count = 0;
while(iss >> i)
{
if(iss.eof())//at end of each line, ends loop
{
count++;
storage[m] = i;
m++;
printf("%d \n", i);
break;
}
else
{
count++;
storage[m] = i;
m++;
printf("%d ", i);
}
}
}
}
int **matrix;
matrix = new int*[count];
for(int y = 0; y < count; y++)
matrix[y] = new int[count];
for(int r = 0; r < count; r++)
for(int c = 0; c < count; r++)
matrix[r][c] = storage[r+c];
printf("first = %d ", matrix[0][0]);
system("PAUSE");
return 0;
}
Based on my input, I should create a 5 x 5 array. But the line
int matrix[count][count];
Gives me an error saying that the "count" size parameter should be a constant. Is my way of counting the size of the input to use an invalid way of doing this, or is there a way to create a constant to use as my size param?

Instead of using 2D native C++ arrays, consider using a vector of vectors.
#include <vector>
#include <iostream>
int main() {
using namespace std;
int count = 5;
// create a matrix of 'count' rows by 0 columns
vector<vector<int>> matrix(count);
// resize the column count for each row
for (auto& r : matrix)
r.resize(count);
// use it just like an array
for (int i = 0; i < count; ++i)
matrix[i][i] = i;
for (int r = 0; r < count; ++r) {
for (int c = 0; c < count; ++c)
cout << matrix[r][c] << ' ';
cout << endl;
}
}

you will need to use a dynamic array
int *myArray; //Declare pointer to type of array
myArray = new int[x]; //use 'new' to create array of size x
myArray[3] = 10; //Use as normal (static) array
...
delete [] myArrray; //remeber to free memeory when finished.
http://www.cplusplus.com/forum/beginner/1601/
http://www.cplusplus.com/doc/tutorial/dynamic/

You are not going to get a 2-D array. You will have to work with Array of Array.
If you are willing to work with dynamic allocations, please do something like this:
int *myArray = new int [count]; // variable length array can get you into trouble here,
// if you are not careful as the inner dimension needs
// to be freed before the array goes out of scope.
for (/*iterate from 0 count*/) {
myArray[i] = new int [count];
}
myArray[m][n] to give you a semblance of what you wanted.

Related

Problem using iterators with dynamically allocated array

I have a variable k of type int to set the length of a dynamically allocated int array:
int *Numbers = new int[k];
But because of this I cannot iterate over the array, I get an error:
"no matching begin function was found required for this range-based for statement"
I also cannot get the length of the array using size();
Here's the complete code:
#include <iostream>
using namespace std;
int main()
{
int b, k;
cin >> b >> k;
int *Numbers = new int[k];
for (int i : Numbers) {// (There is a error)
}
for (int i = 0; i < size(Numbers); i++) {
}
}
Prefer using a std::vector instead of a std::array. (Like #tadman mentioned.)
Here is your code using std::vector instead:
#include <iostream>
#include <vector>
int main()
{
int b, k;
std::cin >> b >> k;
std::vector<int> Numbers(b,k); // Fills the vector "Numbers" with nth number of elements with each element as a copy of val.
for (int i : Numbers)
std::cout << i << std::endl;
for (int i = 0; i < Numbers.size(); i++)
std::cout << Numbers[i] << std::endl;
return 0;
}
Say I want 10 elements with the number 5.
Output:
10
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
Also consider not using namespace std;.
The simple and recommended solution is to use std::vector, however if you really want a dynamically allocated array and to use iterator like features on it, you can use iterator_range from boost library, which allows you to create an iterator range for it thus making it usable in range based for loops and in functions like std::size.
Live demo
#include <iostream>
#include<boost/range.hpp>
int main()
{
int k = 5;
int *Numbers = new int[k]{1,4,5,7,8};
auto arr = boost::make_iterator_range(Numbers, Numbers + k);
for (int i : arr) { //range based loop
std::cout << i << " ";
}
std::cout << std::endl << "Size: " << arr.size(); //print size
//or std::size(arr);
}
Output:
1 4 5 7 8
Size: 5
Range-based for loops work with arrays, but not work with pointers. The Actual issue is that arrays is actually a pointer and not an array.try to use simple array.
Using pointers is problematic for many reasons. The simple solution to your problem is to use a vector
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int b, k;
cin >> b >> k;
vector<int> Numbers(k);
for (int i : Numbers) {
cout << i << endl;
}
for (int i = 0; i < Numbers.size(); i++) {
cout << Numbers[i] << endl;
}
}
C array does not have default iterator and thus there is no begin() and end() functions that are used to iterate over array when you use statment like this:
for (int i : Numbers)
You can check range-for reference:
range_expression - any expression that represents a suitable sequence (either an array or an object for which begin and end member functions or free functions are defined, see below) or a braced-init-list.
Okay, so since the dynamic array does not have a default iterator, do not use the for-each loop, instead consider using the regular for loop.
Also, mind the the size function will not work for an array (or dynamic array) and you need to remember the size, since it's not possible to get the size from the pointer only. Hence, this code would work:
#include <iostream>
using namespace std;
int main()
{
int b, k;
cin >> b >> k;
int *Numbers = new int[k];
const int SIZE = k;
for (int i = 0; i < SIZE; i++) {
cout << i << ' ';
}
}
You need to dereference *Numbers by using the * if you want to iterate over the array because *Numbers is a pointer to an integer which points to the first element of your array.For Example :
#include <iostream>
using namespace std;
int main()
{
int k = 10;
int *numbers = new int[k];
//filling the array
for(int i = 0 ; i < k ; ++i) {
*(numbers + i) = i ;
}
//output array element
for(int i = 0 ; i < k ; ++i) {
cout << numbers + i << " is the address of "<<*(numbers + i) << endl;
}
return 0;
}
The output is :
0x6f1750 is the address of 0
0x6f1754 is the address of 1
0x6f1758 is the address of 2
0x6f175c is the address of 3
0x6f1760 is the address of 4
0x6f1764 is the address of 5
0x6f1768 is the address of 6
0x6f176c is the address of 7
0x6f1770 is the address of 8
0x6f1774 is the address of 9
Unfortunatly, you can't get the size of your array with *Numbers because it's not an array but a pointer.

2D Vectors Char to Int

I am trying to convert a 2D Vectors of randomly generated chars to int. For example, if the chars are 'abc' then I want my int vector to be '97,98,99' etc.
I tried looking on here and for the most part, people are asking about char to sting, string to char, etc.
This is what I have so far.
#include <vector>
#include <cstdlib>
#include <string>
#include <iostream>
using namespace std;
int main()
{
vector<vector<char> > vec(100, vector<char>(10));
vector<vector<int> > intVec(100, vector<int>(10));
srand(time(NULL));
int intAscii = 0;
// Fill 2D vector with random chars
for(int i = 0; i < 1; i++)
{
rand_num = (rand() % 8 + 3);
for(int j = 0; j < rand_num; j++)
{
//logic here... randomly gen a char and place it in the same position, but this time in the int vector as an int.
vec.at(i).push_back((rand() % 26 + 97));
intAscii = int(vec.at(i).at(j));
intVec.at(i).push_back(intAscii);
}
// Print Contents & print out the int vector.
for(int i = 0; i < vec.size(); i++)
{
for(int j = 0; j < vec.at(i).size(); j++)
{
cout << vec.at(i).at(j);
cout << intVec.at(i).at(j);
}
}
}
The problem that I am running into is that when it prints out both vectors, chars is fine, for int I am getting a whole bunch of zeros. Which doesn't seem right because the int(vec.at(i).at(j)) works i.e if char vector was a then the int vector would be 97 and so on.
At this point, my guess is that the syntax for the int vector might be wrong.
You may try this:
intAscii = (int)vec.at(i).at(j);
In addition, to access the elements it could be better to use indices instead of push_back, like:
intVec.at(i).at(j) = intAscii;
This should work because you already allocate memory for your vector at the very beginning.

Regarding pointers and arrays and how they are assigned in memory in C++

So I am trying to solve this question:
Data is fed in the following input format. The first line contains two space-separated integers denoting the number of variable-length arrays, n, and the number of queries, q. Each line of the subsequent lines contains a space-separated sequence in the format
k Ai[0] Ai[1] … Ai[k-1]
where k is the length of the array, Ai, and is followed by the k elements of Ai. Each of the subsequent lines contains two space-separated integers describing the respective values of array number (ranging from 0 to n-1) and index in that particular array (ranging from 0 to ki) for a query. i.e, Given the following input:
3 3
3 1 2 3
5 4 5 6 7 8
4 9 10 11 12
0 1
1 3
2 0
This output is expected
2
7
9
I am basically a beginner in C++. This is the code I have tried but I feel the address at which each subsequent array is stored is giving me some problems
int main(){
int n, q;
scanf("%d %d", &n, &q);
printf("n,q = %d, %d\n", n, q);
int* row[n];
for (int i = 0; i < n; i++){
int k;
scanf("%d", &k);
printf("k = %d\n", k);
int col[k];
row[i] = col;
for (int j = 0; j < k; j++){
int elem;
scanf("%d", &elem);
printf("i,j,elem = %d, %d, %d\n", i, j, elem);
col[j] = elem;
cout << "address is " << &(col[j]) << "\n";
}
}
for (int query = 1; query <= q; query++){
int i, j;
scanf("%d %d", &i, &j);
int answer;
answer = *(row[i] + j);
printf("row[%d][%d] is %d\n", i, j, answer);
cout << "address is " << &answer << "\n";
}
return 0;
}
And this is the output produced:
n,q = 3, 3
k = 3
i,j,elem = 0, 0, 1
address is 0x7ffe236edb70
i,j,elem = 0, 1, 2
address is 0x7ffe236edb74
i,j,elem = 0, 2, 3
address is 0x7ffe236edb78
k = 5
i,j,elem = 1, 0, 4
address is 0x7ffe236edb60
i,j,elem = 1, 1, 5
address is 0x7ffe236edb64
i,j,elem = 1, 2, 6
address is 0x7ffe236edb68
i,j,elem = 1, 3, 7
address is 0x7ffe236edb6c
i,j,elem = 1, 4, 8
address is 0x7ffe236edb70
k = 4
i,j,elem = 2, 0, 9
address is 0x7ffe236edb60
i,j,elem = 2, 1, 10
address is 0x7ffe236edb64
i,j,elem = 2, 2, 11
address is 0x7ffe236edb68
i,j,elem = 2, 3, 12
address is 0x7ffe236edb6c
row[0][1] is 32766
address is 0x7ffe236edbcc
row[1][3] is 32766
address is 0x7ffe236edbcc
row[2][0] is 3
address is 0x7ffe236edbcc
Basically, I find that the array addresses are overlapping. Also, The answer computation by dereferencing is resulting in unexpected outputs. Any explanation to the mistakes made here would be appreciated.
Here is a major problem:
for (int i = 0; i < n; i++){
...
int col[k];
row[i] = col;
...
}
The variable col has its scope only inside the loop. Once the loop iterates the variable cease to exist. Storing a pointer to it will lead to undefined behavior when you try to dereference the pointer.
The simple solution is probably to dynamically allocate memory for col using malloc.
Missed that the question was tagged C++, and confused because the source doesn't actually use any C++-specific code. This kind of makes it worse since variable-length arrays are not part of C++. Some compilers have it as an extension, but you should not use it when programming in C++.
Instead you should be using std::vector and then you can easily solve your problem without your own dynamic allocation. Then you can make row a vector of vectors of int and col a vector of int, and then the assignment will work fine (if row have been set to the correct size of course).
An easy way to use C++ without getting too many memory management bugs is to use standard library types. Leave the bare metal stuff to the poor C guys who do not have that ;)
So instead of meddling with new[] and delete[], use types like std::vector<> instead.
The "modern C++" version below uses iostream for no good reason. Old stdio.h is sometimes the preferred choice and so is sometimes iostream. And sometimes it is just a matter of style and taste.
#include <vector>
#include <iostream>
#include <fstream>
typedef struct Q
{
int iArray;
int iIndex;
} Q_t;
typedef std::vector<std::vector<int> > Data_t;
typedef std::vector<Q_t> Query_t;
bool Load(Data_t& data, Query_t &queries, std::istream& is)
{
size_t ndata = 0;
size_t nqueries = 0;
is >> ndata;
is >> nqueries;
data.resize(ndata);
queries.resize(nqueries);
for (size_t d = 0; d < ndata; d++)
{
size_t l = 0;
is >> l;
data[d].resize(l);
for (size_t i = 0; i < l; i++)
{
is >> data[d][i];
}
}
for (size_t q = 0; q < nqueries; q++)
{
is >> queries[q].iArray;
is >> queries[q].iIndex;
}
return true;
}
int main(int argc, const char * argv[])
{
std::ifstream input("E:\\temp\\input.txt");
Data_t data;
Query_t queries;
if (Load(data, queries, input))
{
for (auto &q : queries)
{
std::cout << data[q.iArray][q.iIndex] << std::endl;
}
}
return 0;
}
The mistake is, you have used 'col' array which loses its scope after completion of for loop. The way you can fix this is by either using dynamic memory allocation or by declaring it outside the for loop
Hope the below code will help you get an idea :)
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n, q;
cin >> n;
cin >> q;
int* row[n];
int* col;
for(int i=0; i<n; i++)
{
int k;
cin >> k;
col = new int[k];
row[i] = col;
for(int j=0; j<k; j++)
{
cin >> col[j];
}
}
for(int query=0; query<q; query++)
{
int i,j;
cin >> i;
cin >> j;
cout << row[i][j] << endl;
}
delete[] col;
return 0;
}

copying elements from one array to another

I am getting a crash error at run time and not sure what exactly to do with the function or how to get the data for it.
FUNCTION DETAILS
Write a function that accepts an int array and size as arguments, then create a new array that is one element bigger than the given. Setting the first element to 0, then copying over what is in the argument array to the new array.
MAIN DETAILS
Use in a program reading int n from input, then read int n from file data name data
passing it to element shifter, then printing it to output (one per line).
#include <cstdlib>
#include <iostream>
#include <fstream>
using namespace std;
int element_shift(int elmts[], int size) {
int new_size = size + 1;
int shifter[new_size];
int *elmt_sft;
shifter[0] = 0;
for (int i = 1; i >= new_size; i++) {
shifter[i + 1] = elmts[i];
}
return *elmt_sft;
}
int main() {
fstream infile;
infile.open("D:\\data.txt");
int n, x;
infile >> x;
cout << "size of array: ";
cin >> n;
const int ARRAY_SIZE = n + x;
int elements[ARRAY_SIZE];
element_shift(elements, ARRAY_SIZE);
system("PAUSE");
return EXIT_SUCCESS;
}
First of all ARRAY_SIZE declared in the main function is not a constant variable but defined at run-time depending on user inputs. This means that the array elements should be created dynamically. On the other hand you read some x variable which is only used to define the size of the array and didn't initialized the array at all. I guess that the problem statement is to read the size of the array from the input, then the data of the array from the file.
There are also lot of mistakes in element_shift function.
Your code should look like something similar to this:
#include <cstdlib>
#include <iostream>
#include <fstream>
using namespace std;
void element_shift(int* elmts, int size)
{
int new_size = size + 1;
int* shifter = new int[new_size];
shifter[0] = 0;
for(int i = 0; i < size; ++i)
{
shifter[i + 1] = elmts[i];
}
delete [] elmts;
elmts = shifter;
}
int main()
{
fstream infile;
infile.open("D:\\data.txt");
int n;
cout << "size of array: ";
cin >> n;
int* elements = new int[n];
for (int i = 0; i < n; ++i) {
infile >> elements[i];
}
element_shift(elements, n);
for (int i = 0; i < n; ++i) {
std::cout << elements[i] << std::endl;
}
return EXIT_SUCCESS;
}
First off, you spend alot of time creating the shifted array but don't return it back.
int element_shift(int elmts[], int size) {
int new_size = size + 1;
int shifter[new_size];
int *elmt_sft;
shifter[0] = 0;
for (int i = 1; i >= new_size; i++) {
shifter[i + 1] = elmts[i];
}
return *elmt_sft;
}
The elmt_sft pointer is never assigned. You are trying to access memory that is not there by using *elmt_sft. This may be causing your error. Also this function has no way of returning the new array shifter because that variable is locally declared and will disappear once the function exits. If you want to create something new in the function and still have it in memory once the function exits, I recommend creating the array dynamically and returning a pointer to it.
This is untested but should start you in the right direction. It will return a separate dynamically allocated array that will not override your other one.
int* element_shift(int elmts[], int size) {
int *result_array = new int[size + 1]; //dynamically create new array MAKE SURE TO DELETE
result_array[0] = 0; //set 0 index to 0
for (int i = 1; i < size + 1; i++)//start at 1 of the result and put value in
{
result_array[i] = elmts[i - 1];
}
return result_array; //returning pointer
}

Do jagged arrays exist in C/C++?

Is there such a thing as a jagged array in C or C++?
When I compile this:
int jagged[][] = { {0,1}, {1,2,3} };
I get this error:
error: declaration of `jagged' as multidimensional array must have bounds for all dimensions except the first
In C I would use an array of pointers.
For instance:
int *jagged[5];
jagged[0] = malloc(sizeof(int) * 10);
jagged[1] = malloc(sizeof(int) * 3);
etc etc.
There's a bunch of ways to do it. Here's another way:
int jagged_row0[] = {0,1};
int jagged_row1[] = {1,2,3};
int *jagged[] = { jagged_row0, jagged_row1 };
If you just want to initialise it, you can say:
int jagged[][3] = { {0,1}, {1,2,3} };
but the array will still have the shape [2][3]. If you want a true jagged array, you will have to create it dynamically. And if you do that, and are using C++, you should use a std::vector, as friol suggests.
In C++ (not compiled, and probably there's a more compact syntax):
std::vector<std::vector<int> > myArray;
myArray.push_back(std::vector<int>());
myArray.push_back(std::vector<int>());
myArray[0].push_back(0);
myArray[0].push_back(1);
myArray[1].push_back(1);
myArray[1].push_back(2);
myArray[1].push_back(3);
So now you can access the elements with, for example, myArray[0][0], etc.
In C99 you can do the following:
int jagged_row0[] = {0,1};
int jagged_row1[] = {1,2,3};
int (*jagged[])[] = { &jagged_row0, &jagged_row1 }; // note the ampersand
// also since compound literals are lvalues ...
int (*jagged2[])[] = { &(int[]){0,1}, &(int[]){1,2,3} };
The only difference here (as compared to rampion's answer) is that the arrays don't decay to pointers and one has to access the individual arrays via another level of indirection - (e.g. *jagged[0] - and the size of each row has to be recorded - i.e. sizeof(*jagged[0]) will not compile) - but they're jagged-appearing to the bone ;)
The reason you got the error is that you must specify the bounds for at least the outer dimension; i.e.
int jagged[][3] = {{0,1},{1,2,3}};
You cannot have jagged[0] be a 2-element array of int and jagged[1] be a 3-element array of int; an N-element array is a different type from an M-element array (where N != M), and all elements of an array must be the same type.
What you can do is what the others have suggested above and create jagged as an array of pointers to int; that way each element can point to integer arrays of different sizes:
int row0[] = {0,1};
int row1[] = {1,2,3};
int *jagged[] = {row0, row1};
Even though row0 and row1 are different types (2-element vs. 3-element arrays of int), in the context of the initializer they are both implicitly converted to the same type (int *).
With C++11 initializer lists this can be written more compactly:
#include <vector>
#include <iostream>
int main() {
// declare and initialize array
std::vector<std::vector<int>> arr = {{1,2,3}, {4,5}};
// print content of array
for (auto row : arr) {
for (auto col : row)
std::cout << col << " ";
std::cout << "\n";
}
}
The output is:
$ g++ test.cc -std=c++11 && ./a.out
1 2 3
4 5
For reference:
http://en.cppreference.com/w/cpp/utility/initializer_list
You can also use the compound literals in c to initialize a truly jagged array which is contiguous in memory as follows:
int (*arr[]) = { (int []) {0, 1}, (int []){ 2, 3, 4}, (int []){5, 6, 7, 8} }
This will be laid out contiguously in memory.
By using dynamic allocation in cpp we can create jagged arrays.
For example:
#include<iostream>
using namespace std;
int main(){
int n;
cout<<"Enter n:";
cin>>n;
cout<<"Enter elements:";
int **p = new int *[n];
for(int i=0;i<n;i++){
p[i] = new int[i+1];
for(int j=0;j<(i+1);j++){
cin>>p[i][j];
}
}
cout<<"Jagged Array:"<<endl;
for(int i=0;i<n;i++){
for(int j=0;j<(i+1);j++){
cout<<p[i][j]<<" ";
}
cout<<endl;
}
for(int i=0;i<n;i++){
delete []p[i];
}
delete []p;
}
For n=3, we have created a jagged array in the following look:
Enter n: 3
Enter elements:
1
1 2
1 2 3
Jagged Array:
1
1 2
1 2 3
//
//jaggedArrays.cpp
//
//program to implement jagged arrays in c++
//
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
int rows, i, j;
cout << endl << "Enter no of rows : ";
cin >> rows;
int columnsSizeOfEachRow[rows];
cout << endl;
for( i = 0 ; i < rows ; i++ )
{
cout << "Enter column size for row no " << i + 1 << " : ";
cin >> columnsSizeOfEachRow[i];
}
int *jaggedArray[rows];
for (i = 0 ; i < rows ; i++)
jaggedArray[i] = new int[columnsSizeOfEachRow[i]];
cout << endl;
for(i = 0 ; i < rows ; i++)
{
for ( j = 0 ; j < columnsSizeOfEachRow[i] ;j++)
{
cout << "Array[" << i + 1 << "][" << j + 1 << "] << ";
cin >> jaggedArray[i][j];
}
cout << endl;
}
cout << endl << endl << "Jagged array is as follows : " << endl;
for( i = 0 ; i < rows ; i++)
{
for ( j = 0 ; j < columnsSizeOfEachRow[i] ;j++)
cout << setw(3) <<jaggedArray[i][j] << " ";
cout << endl;
}
return 0;
}
The jagged arrays do exist in c++/c but the syntax is quite complex and you have to handle many things.
There are two types of jagged arrays in c++.
1) STATIC JAGGED ARRAY(A 2d array in which the size will be a constant number and there will be different number of columns in each row).
2) DYNAMIC JAGGED ARRAY(A 2d array in which the size will be any number taken from user and there will be different number of columns in each row)
1)STEPS OF IMPLEMENTING STATIC JAGGED ARRAY
Using array and a pointer
1) Declare 1-D arrays with the number of rows you will need
2) The size of each array(array for the elements in the row) will be the number of columns (or elements) in the row
3) Declare a 1-D array of pointers that will hold the addresses of the arrows
4) The size of the 1-D array is the number of rows you want in the jagged array
#include<iostream>
#include<string>
using namespace std;
int main()
{
int row0[4] = { 1,2,3,4 };
int row1[2] = { 5,6 };
int* jagged[2] = { row0,row1 };
int Size[2] = { 4,2 }, k = 0;
for (int i = 0; i < 2; i++)
{
int* ptr = jagged[i];
for (int j = 0; j < Size[k]; j++)
{
cout << *ptr << "";
ptr++;
}
cout << endl;
k++;
jagged[i]++;
}
return 0;
}
The output is as follows
123456
1)STEPS OF IMPLEMENTING DYNAMIC JAGGED ARRAY
Using an array of pointer
1) Declare an array of pointers(jagged array)
2) The size of this array will be the number of rows required in the jagged array
3) For each pointer in the array allocate memory for the number of elements you want in this row.
#include<iostream>
#include<string>
using namespace std;
int main()
{
//2 rows
int* jagged[2];
//Allocate memeory for the elements in the row 0
jagged[0] = new int[1];
//Allocate memory for the elements in row 1
jagged[1] = new int[5];
//Array to hold the size of each row
int Size[2] = { 1,5 },k = 0, number = 100;
//User enters the numbers
for (int i = 0; i < 2; i++)
{
int* p = jagged[i];
for (int j = 0; j < Size[k]; j++)
{
*p = number++;
//move the pointer
p++;
}
k++;
}
k = 0;
//Display elements in Jagged array
for (int i = 0; i < 2; i++)
{
int* q = jagged[i];
for (int j = 0; j < Size[k]; j++)
{
cout << *q << "";
//move the pointer to the next element
q++;
}
cout << endl;
k++;
//move the pointer to the next row
jagged[i]++;
}
delete[] jagged[0];
delete[] jagged[1];
return 0;
}
The output is as follows
100
101102103104105
No, there are no jagged multidimensional arrays in C nor C++. You can create various constructs that perform similar function at some memory cost (like array of pointers to arrays), but not an actual C-style multidimensional array.
The reason is that C-style arrays, no matter how many dimensions, occupy contiguous memory area with no metadata. So, memory-wise, they're all single-dimensional. It's only the cleverness of pointer arithmetic (striding the pointer by the size of a row) that gives you the functionality of extra dimensions. A jagged array laid out serially has different row sizes, so it cannot be strode by a constant value, so it requires additional storage depending on data size, thus is impossible to express in C type system.
It becomes clearer when you consider to what pointer multidimensional array decay to: Array to pointer decay and passing multidimensional arrays to functions
And that's why you see the error message must have bounds for all dimensions except the first, because all dimensions except the first are necessary to stride the array.