Velocity Reviews > C++ > Problem with assigning 1D array to a 2D array

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

bintom
Guest
Posts: n/a

 10-12-2012
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

Victor Bazarov
Guest
Posts: n/a

 10-12-2012
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

bintom
Guest
Posts: n/a

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

Ike Naar
Guest
Posts: n/a

 10-12-2012
On 2012-10-12, Victor Bazarov <(E-Mail Removed)> 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
Guest
Posts: n/a

 10-12-2012
On 2012-10-12, bintom <(E-Mail Removed)> 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

Victor Bazarov
Guest
Posts: n/a

 10-12-2012
On 10/12/2012 1:39 PM, Ike Naar wrote:
> On 2012-10-12, Victor Bazarov <(E-Mail Removed)> 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

bintom
Guest
Posts: n/a

 10-12-2012
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.

Luca Risolia
Guest
Posts: n/a

 10-13-2012
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], ++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

Juha Nieminen
Guest
Posts: n/a

 10-13-2012
A. Bolmarcich <(E-Mail Removed)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.

Luca Risolia
Guest
Posts: n/a

 10-13-2012
On 13/10/2012 22:36, Juha Nieminen wrote:
> A. Bolmarcich <(E-Mail Removed)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.