# Problem with assigning 1D array to a 2D array

Discussion in 'C++' started by bintom, Oct 12, 2012.

1. ### bintomGuest

I am trying to write a program with a function int** One2Two(int *a, int size, int (*A)[10]) that takes the address of a1D int array (A1) , the size of A1 and the address of a 2D int array (A2). The function should copy the values of A1 and store them in A2 as suggested by the pattern below:

If A1 is 1, 2, 3:
then A2 should be 1 0 0
1 2 0
1 2 3

If A1 is 1, 2, 3, 4, 5:
then A2 should be 1 0 0 0 0
1 2 0 0 0
1 2 3 0 0
1 2 3 4 0
1 2 3 4 5

My program is given below:

#include <iostream>

using namespaces std;

int** One2Two(int *a, int size, int (*A)[10])
{ int i, j;

for(i=0; i<size; i++)
{ for(j=0; j<=i; j++)
**(A+i*size+j) = *(a+i);
for(; j<size; j++)
**(A+i*size+j) = *(a+i);
}
}

int main()
{ int a[10], (*A)[10], size, i, j;
a[0]=1; a[1]=2; a[2]=3; a[3]=4; a[4]=5;
size = 5;

One2Two(a, size, A);

for(i=0; i<size; i++)
{ for(j=0; j<size; j++)
cout << **(A+i*size+j) << " ";
cout << "\n";
}
}

However, my program hangs in the inner loop of the function and I have to close the program run. Can anybody help me figure out what the problem is???

T. V. Thomas

bintom, Oct 12, 2012

2. ### Victor BazarovGuest

On 10/12/2012 6:22 AM, bintom wrote:
> I am trying to write a program with a function int** One2Two(int *a,

int size, int (*A)[10]) that takes the address of a1D int array (A1) ,
the size of A1 and the address of a 2D int array (A2). The function
should copy the values of A1 and store them in A2 as suggested by the
pattern below:
>
> If A1 is 1, 2, 3:
> then A2 should be 1 0 0
> 1 2 0
> 1 2 3
>
> If A1 is 1, 2, 3, 4, 5:
> then A2 should be 1 0 0 0 0
> 1 2 0 0 0
> 1 2 3 0 0
> 1 2 3 4 0
> 1 2 3 4 5
>
> My program is given below:
>
> #include <iostream>
>
> using namespaces std;
>
> int** One2Two(int *a, int size, int (*A)[10])
> { int i, j;
>
> for(i=0; i<size; i++)
> { for(j=0; j<=i; j++)
> **(A+i*size+j) = *(a+i);
> for(; j<size; j++)
> **(A+i*size+j) = *(a+i);
> }
> }
>
> int main()
> { int a[10], (*A)[10], size, i, j;

'A' is an array of 10 pointers to int. 'a' is an array of 10 ints.

> a[0]=1; a[1]=2; a[2]=3; a[3]=4; a[4]=5;

Here you assign ints to ints. That's perfectly fine.

> size = 5;
>
> One2Two(a, size, A);

Here you pass an array of 10 pointers to int (10 pointers) to the
function. That function will dereference those pointers. Where do
those pointers point to?

>
> for(i=0; i<size; i++)
> { for(j=0; j<size; j++)
> cout << **(A+i*size+j) << " ";
> cout << "\n";
> }
> }
>
> However, my program hangs in the inner loop of the function and I
> have to close the program run. Can anybody help me figure out what
> the problem is???

You dereference uninitialized pointers. Your program has undefined
behavior. Anything is allowed to happen. Read up on "nasal demons".

V
--
I do not respond to top-posted replies, please don't ask

Victor Bazarov, Oct 12, 2012

3. ### bintomGuest

I initialized A to 0, yet the problem persists. Can somebody else help with a solution? Thanks.

bintom, Oct 12, 2012
4. ### Ike NaarGuest

On 2012-10-12, Victor Bazarov <> wrote:
> On 10/12/2012 6:22 AM, bintom wrote:
>> int main()
>> { int a[10], (*A)[10], size, i, j;

>
> 'A' is an array of 10 pointers to int. 'a' is an array of 10 ints.

'A' is a pointer to an array of 10 ints.

An array of 10 pointers to int is declared as 'int *A[10];',
or, with explicit parentheses, 'int *(A[10]);'.

Ike Naar, Oct 12, 2012
5. ### Ike NaarGuest

On 2012-10-12, bintom <> wrote:
> I am trying to write a program with a function int** One2Two(int *a,
> int size, int (*A)[10]) that takes the address of a 1D int array (A1),
> the size of A1 and the address of a 2D int array (A2).

You are confused.

The parameter 'a' (or 'A1') is a pointer-to-int, or, likewise, the
address of an int; it's not the address of a 1D int array (but it
could be the address of the first element of such an array).

'A' (or 'A2') is a pointer to a 1D array (more precisely, a pointer
to an array of 10 ints), or, likewise, the address of such an array;
it's not the address of a 2D array.

Why is the return type of One2Two pointer-to-pointer-to-int when
the function does not return anything?

Have a look chapter 6 of the C language FAQ,

http://c-faq.com/aryptr/index.html

Ike Naar, Oct 12, 2012
6. ### Victor BazarovGuest

On 10/12/2012 1:39 PM, Ike Naar wrote:
> On 2012-10-12, Victor Bazarov <> wrote:
>> On 10/12/2012 6:22 AM, bintom wrote:
>>> int main()
>>> { int a[10], (*A)[10], size, i, j;

>>
>> 'A' is an array of 10 pointers to int. 'a' is an array of 10 ints.

>
> 'A' is a pointer to an array of 10 ints.

You're right, of course. I totally missed the parentheses; shows how
much I've been lately using naked pointers and arrays of them.

> An array of 10 pointers to int is declared as 'int *A[10];',
> or, with explicit parentheses, 'int *(A[10]);'.
>

V
--
I do not respond to top-posted replies, please don't ask

Victor Bazarov, Oct 12, 2012
7. ### bintomGuest

I too am coming to the conclusion that I AM confused. But given the problem I amim to solve, it would be great if u could hold my hand and show me the correct way of coding in this case.

And if u could explain why you chose that style of coding, that would be a bonus.

bintom, Oct 12, 2012
8. ### Luca RisoliaGuest

On 12/10/2012 12:22, bintom wrote:
> I am trying to write a program with a function int** One2Two(int *a,
> int size, int (*A)[10]) that takes the address of a1D int array (A1)
> , the size of A1 and the address of a 2D int array (A2). The function
> should copy the values of A1 and store them in A2 as suggested by the
> pattern below:
>
> If A1 is 1, 2, 3: then A2 should be 1 0 0 1 2 0 1 2 3
>
> If A1 is 1, 2, 3, 4, 5: then A2 should be 1 0 0 0 0 1 2 0 0 0 1 2 3 0
> 0 1 2 3 4 0 1 2 3 4 5

Use valarrays for numerical calculations:

#include <iostream>
#include <valarray>

using namespace std;

template<class T>
valarray<T> One2Two(const valarray<T>& v) {
const auto n = v.size();
valarray<T> m(n * n);
for (decltype(v.size()) i = 0; i < n;
m[slice(n * i + i, n - i, n)] = v, ++i);
return m;
}

int main() {
valarray<int> a = {1, 2, 3, 4, 5};
auto m = One2Two(a);
for (const auto& e : m)
cout << e << (((&e - &m[0]) + 1) % a.size() ? ' ' : '\n');
return 0;
}

1 0 0 0 0
1 2 0 0 0
1 2 3 0 0
1 2 3 4 0
1 2 3 4 5

Luca Risolia, Oct 13, 2012
9. ### Juha NieminenGuest

A. Bolmarcich <9.net> wrote:
> Although to be more in the spirit of C++, you should use C++
> vectors rather than arrays.

There's nothing in the "spirit of C++" that would require using vectors
instead of static arrays. If anything, std::array would be the one to be
used instead of static C arrays.

Juha Nieminen, Oct 13, 2012
10. ### Luca RisoliaGuest

On 13/10/2012 22:36, Juha Nieminen wrote:
> A. Bolmarcich <9.net> wrote:
>> Although to be more in the spirit of C++, you should use C++
>> vectors rather than arrays.

>
> There's nothing in the "spirit of C++" that would require using vectors
> instead of static arrays. If anything, std::array would be the one to be
> used instead of static C arrays.

std::valarray would be even more in the "spirit of C++" with regard to
the OP problem.

Luca Risolia, Oct 14, 2012
11. ### Juha NieminenGuest

Luca Risolia <> wrote:
> On 13/10/2012 22:36, Juha Nieminen wrote:
>> A. Bolmarcich <9.net> wrote:
>>> Although to be more in the spirit of C++, you should use C++
>>> vectors rather than arrays.

>>
>> There's nothing in the "spirit of C++" that would require using vectors
>> instead of static arrays. If anything, std::array would be the one to be
>> used instead of static C arrays.

>
> std::valarray would be even more in the "spirit of C++" with regard to
> the OP problem.

Why is std::valarray better as a substitute for a static array given
that it's a container that allocates the memory dynamically, while
std::array allocates it statically (thus being more efficient for
fixed-sized arrays)?

Juha Nieminen, Oct 15, 2012
12. ### Luca RisoliaGuest

On 15/10/2012 08:12, Juha Nieminen wrote:
> Luca Risolia <> wrote:
>> On 13/10/2012 22:36, Juha Nieminen wrote:
>>> A. Bolmarcich <9.net> wrote:
>>>> Although to be more in the spirit of C++, you should use C++
>>>> vectors rather than arrays.
>>>
>>> There's nothing in the "spirit of C++" that would require using vectors
>>> instead of static arrays. If anything, std::array would be the one to be
>>> used instead of static C arrays.

>>
>> std::valarray would be even more in the "spirit of C++" with regard to
>> the OP problem.

>
> Why is std::valarray better as a substitute for a static array given
> that it's a container that allocates the memory dynamically, while
> std::array allocates it statically (thus being more efficient for
> fixed-sized arrays)?

...because efficiency was not the concern of the OP. He asked how to make
his program correct. The easy way to write a program correctly is to
choose the right data structure: as opposite to std::static_array,
std::valarray offers the right interface to compute a subset of its
elements, via slices, to produce the kind of matrix expected by the OP.
Even in the case efficiency is a matter, std::valarray has been designed
to allow compiler/implementation optimizations during its operations,
and, depending on the kind/complexity of the numerical algorithms, that
might be a benefit if most of the time is not spent for memory allocations.

Luca Risolia, Oct 15, 2012