Emre Turkoz
Emre Turkoz

Reputation: 868

Initializing series of arrays with for loops at C++

I try to create series of multidimensional arrays with for loops. User should input the number of arrays to be initialized. I want something like this:

int i;
printf("Enter the number of arrays you want: ");
scanf("%d",i)
for(int j=0;j<i;j++){
     long double x(j)[size][size];
}

if I input 5, I want to have x0, x1, x2, x3 and x4.

Is it possible at all??

Thank you for any help.

Best Regards, Emre.

Upvotes: 0

Views: 3048

Answers (3)

Merlyn Morgan-Graham
Merlyn Morgan-Graham

Reputation: 59111

A set of multi-dimensional arrays is the same thing as a multi-dimensional array with one more dimension.

Also, a couple of things about built-in arrays:

  • In C++, the built-in array dimensions must be based off a compile time constant. You can't calculate the size, read it from a file, get it from user input, etc
  • To create a built-in array with variable size, you must allocate memory, and use it like a pointer
  • To have an allocation for a built-in array be portable between C and C++, you must use malloc, and ensure that later you call free on everything you got from malloc (which can sometimes be very hard to get right)

If you are using C++, and don't need to compile your code with a C compiler, I recommend using a vector instead of a built-in array. Vectors don't have to have a constant size, and can be resized whenever you feel like resizing them, often without calling malloc or new in your code

One way to go about this would look like:

#include<iostream>
#include<vector>

int main(int argc, char* argv[])
{
    std::cout << "Enter the number of arrays you want:" << std::endl;

    const int size = 4;
    const int initial_value = 0;
    int i;
    std::cin >> i;

    std::vector<int> sub_sub_array(size, initial_value);
    std::vector<std::vector<int> > sub_array(size, sub_sub_array);
    std::vector<std::vector<std::vector<int> > > array(i, sub_array);

    array[0][1][2] = 5;

    // Print out the full array contents
    for(size_t i = 0; i < array.size(); ++i)
    {
        for(size_t j = 0; j < size; ++j)
        {
            for(size_t k = 0; k < size; ++k)
            {
                std::cout << "(" << j << ", " << k << ") - " << array[i][j][k] << ", ";
            }
            std::cout << "\n";
        }
        std::cout << "\n";
    }
}

Enter the number of arrays you want:
2

(0, 0) - 0, (0, 1) - 0, (0, 2) - 0, (0, 3) - 0,
(1, 0) - 0, (1, 1) - 0, (1, 2) - 5, (1, 3) - 0,
(2, 0) - 0, (2, 1) - 0, (2, 2) - 0, (2, 3) - 0,
(3, 0) - 0, (3, 1) - 0, (3, 2) - 0, (3, 3) - 0,

(0, 0) - 0, (0, 1) - 0, (0, 2) - 0, (0, 3) - 0,
(1, 0) - 0, (1, 1) - 0, (1, 2) - 0, (1, 3) - 0,
(2, 0) - 0, (2, 1) - 0, (2, 2) - 0, (2, 3) - 0,
(3, 0) - 0, (3, 1) - 0, (3, 2) - 0, (3, 3) - 0,

Edit:

The only problem with the solution above is that you may or may not be able to use it in code that expects a built-in array. Judging from your comments, you need it to.

If your existing code can accept one row at a time, then the above solution will work. If it can only accept a 2d array, you'll have to use a different vector structure. See this question for why:

Pass nested C++ vector as built-in style multi-dimensional array

If you need a set of contiguous 2d arrays, here are some options:

std::vector<int*> array_instances(i);
for(size_t j = 0; j < array_instances.size(): ++j)
    array_instances[j] = new int[size * size];

for(size_t j = 0; j < array_instances.size(); ++j)
    existing_code(array_instances[j]);

// When done with the arrays
for(size_t j = 0; j < array_instances.size(): ++j)
    delete[] array_instances[j]; // Make sure to include the brackets after "delete"

Or:

std::vector<int> template_array(size * size, 0);
std::vector<std::vector<int> > array_instances(i, template_array);

for(size_t j = 0; j < array_instances.size(); ++j)
    existing_code(&array_instances[j][0]);

Upvotes: 1

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361352

If you're working in C++, you better should be using std::vector as:

//single dimensional array of double of size 20
std::vector<double>  v1double (20);      
//use like v[i] where  0 <= i < 20

//two dimensional array of double of size  (10 * 20)
std::vector<std::vector<double> >  v2double(10, v1double ); 
//use like v[i][j] where  0 <= i < 10 and 0 <= j < 20

//three dimensional array of double of size (5 * 10 * 20)
std::vector<std::vector<std::vector<double> >  v3double (5, v2double); 
//use like v[i][j][k] where  0 <= i < 5 and 0 <= j < 10 and 0 <= k < 20

Upvotes: 1

hugomg
hugomg

Reputation: 69934

Edit: Just noticed you are using C++. In this case, std::vector is definitely the most convenient solution. If you are curious about how to do this with plain arrays, C style, then read on...


You can't do it like this. What you need to do is create a 3 dimensional array (or an array of 2-dimensional arrays, depending on your point of view...)

As is always the case with C, memory allocation is a pain... You can statically allocate:

long double x[N][size][size];

(N is determined at compile time. Make sure you have it large enough. Also if N is really big, declare the array stactically (either as a global variable or with the static keyword). If you don't you can get a stack-overflow.)

Or you can use dynamic memory allocation:

long double (*x)[size][size]; // x is a pointer to size by size arrays
x = malloc(n * sizeof(*x));
//You can now use x[j][a][b]...

Maybe things look better with a typedef (even I am not 100% sure I got that array ceclaration right in the last example...):

typedef long double typename_here[size][size];
typename_here *x;
x = malloc(n * sizeof(typename_here);

BTW, the reason your current code doesn't work is

  1. The x(j) syntax is ficticious :)
  2. Variables declared inside a loop are internal to that block. This means you can't access them after the loop body.

Upvotes: 1

Related Questions