Problems initializing a dynamically allocated 2D array

M

masood.iqbal

I am having lots of trouble getting a simple program that initializs a
dynamically allocated 2D array to work. My 2D array is not getting
initialized properly, and additionally I am getting a "Null pointer
assignment" error. Kindly help.

Also, eventually I intend to move this logic to a separate function.
For that, I believe, that I will need to pass a
pointer-to-pointer-to-pointer type as an arguent. Please confirm.

[My apologies to C purists --- I am using the new operator instead of
malloc/calloc since I find its usage more intuitive]

Masood



/************************************************************************/
#include <stdio.h>

#define ROWS 3
#define COLUMNS 5


main()
{
int **tbl;
size_t rows = ROWS;
size_t cols = COLUMNS;
int startVal = 2;

tbl = new (int**)[cols];

for(size_t i = 0; i < rows; i++)
tbl = new (int *)[rows];

for(size_t i1 = 0; i1 < rows; i1++)
for(size_t j1 = 0; j1 < cols; j1++)
tbl[i1][j1] = startVal++;

for(size_t i2 = 0; i2 < rows; i2++)
for(size_t j2 = 0; j2 < cols; j2++)
printf("Row: %d, Col: %d => %d\n",
i2, j2, tbl[i2][j2]);
return 0;
}
 
A

Alf P. Steinbach

* (e-mail address removed):
[Cross-posted to C and C++ newsgroups, Not a Good Idea]

Please don't do that
(except where it is an issue of interest to practitioners of both).

Follow-up set to [comp.lang.c++].


* (e-mail address removed):
I am having lots of trouble getting a simple program that initializs a
dynamically allocated 2D array to work. My 2D array is not getting
initialized properly, and additionally I am getting a "Null pointer
assignment" error. Kindly help.

Don't use raw pointers.

Use standard containers like e.g. std::vector.

Then all your current problems disappear.


Also, eventually I intend to move this logic to a separate function.
For that, I believe, that I will need to pass a
pointer-to-pointer-to-pointer type as an arguent. Please confirm.

Pass a reference to the container.

[My apologies to C purists --- I am using the new operator instead of
malloc/calloc since I find its usage more intuitive]

Using 'new' is a good idea when you really need to handle allocation
yourself.

Here you _don't_ need to handle allocation yourself.

Use standard containers like e.g. std::vector.


/************************************************************************/
#include <stdio.h>

#define ROWS 3
#define COLUMNS 5

Preferentially use constants, like e.g.

std::size_t const nRows = 3;
std::size_t const nColumns = 5;


Must have 'int' return value type, both in C and C++.

{
int **tbl;
Indentation.


size_t rows = ROWS;
size_t cols = COLUMNS;

Those should be 'const' (already mentioned).

int startVal = 2;

tbl = new (int**)[cols];

tbl = new (int*)[cols];

for(size_t i = 0; i < rows; i++)
tbl = new (int *)[rows];


tbl = new int[rows];

for(size_t i1 = 0; i1 < rows; i1++)

It's a good idea to use meaningful names, e.g. 'iRow'.

Preferentially use '++i', not 'i++'.

See
<url: http://home.no.net/dubjai/win32cpptut/html/w32cpptut_01_02_11.html>.
<url:
http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.11>
<url:
http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.12>

for(size_t j1 = 0; j1 < cols; j1++)
tbl[i1][j1] = startVal++;

If you had used meaningful names this would have been

tbl[iRow][iColumn] = ++startVal;

which hopefully you can see is incorrect (which index goes where?).

for(size_t i2 = 0; i2 < rows; i2++)
for(size_t j2 = 0; j2 < cols; j2++)
printf("Row: %d, Col: %d => %d\n",
i2, j2, tbl[i2][j2]);
return 0;
}


Use standard containers like e.g. std::vector.
 
A

ajk

main()
{
int **tbl;
size_t rows = ROWS;
size_t cols = COLUMNS;
int startVal = 2;

tbl = new (int**)[cols]; // ok here allocate tbl[0..4]

for(size_t i = 0; i < rows; i++)
tbl = new (int *)[rows]; // tbl[0..4] = int array [0..2] ok

for(size_t i1 = 0; i1 < rows; i1++)
for(size_t j1 = 0; j1 < cols; j1++) // now you are turning it around
tbl[i1][j1] = startVal++; // tbl[0..2][0..4] .. not good

for(size_t i2 = 0; i2 < rows; i2++)
for(size_t j2 = 0; j2 < cols; j2++)
printf("Row: %d, Col: %d => %d\n",
i2, j2, tbl[i2][j2]); // tbl[0..2][0..4] also not good.
return 0;
}


hth/ak
 
G

Gianni Mariani

I am having lots of trouble getting a simple program that initializs a
dynamically allocated 2D array to work. My 2D array is not getting
initialized properly, and additionally I am getting a "Null pointer
assignment" error. Kindly help.

Use a matrix class ... this is just an example (although it works) -
there are some extensive matrix libraries you could use and ones that
are very efficient if the dimensions are known.

#include <vector>

template <typename w_elem_type>
class matrix
{
public:
typedef int t_Size;

t_Size m_columns;
t_Size m_rows;

std::vector<w_elem_type> m_data;

matrix( t_Size i_columns = 0, t_Size i_rows = 0 )
: m_columns( i_columns ),
m_rows( i_rows ),
m_data( i_columns * i_rows )
{
}

w_elem_type * operator[]( t_Size i_index )
{
return & ( m_data[ i_index * m_rows ] );
}

template <typename w_Type, int w_columns, int w_rows>
matrix( const w_Type (&i_array)[w_columns][w_rows] )
: m_columns( w_columns ),
m_rows( w_rows ),
m_data( & (i_array[0][0]), & (i_array[w_columns-1][w_rows]) )
{
}

};

#include <iostream>

double array[3][4] = {
{ 1.0, 2.0, 3.3, 4.4 },
{ 1.0, 2.0, 3.3, 4.4 },
{ 1.0, 2.0, 3.3, 4.5 },

};

int main()
{
matrix<float> mat1( 3, 4 );
matrix<float> mat2;
matrix<float> mat3( array );

mat2 = mat3;

std::cout << mat2[2][3] << "\n";
}
Also, eventually I intend to move this logic to a separate function.
For that, I believe, that I will need to pass a
pointer-to-pointer-to-pointer type as an arguent. Please confirm.

If you use the martix class above, you can pass it by reference, const
reference or value.

void foo( matrix<int> & modify_me );
void foo( const matrix<int> & just_read_me );
void foo( const matrix<int> & make_a_copy_of_me );

Note that the matrix is parameterized on element type.
[My apologies to C purists --- I am using the new operator instead of
malloc/calloc since I find its usage more intuitive]

Try not posting to the C groups if you're really interested in C++.
/************************************************************************/
#include <stdio.h>

#define ROWS 3
#define COLUMNS 5


main()
{
int **tbl;
size_t rows = ROWS;
size_t cols = COLUMNS;
int startVal = 2;

tbl = new (int**)[cols];

tbl = new (int*)[cols]; // this is probably what you wanted
for(size_t i = 0; i < rows; i++)
tbl = new (int *)[rows];


tbl = new (int)[rows]; // again
for(size_t i1 = 0; i1 < rows; i1++)
for(size_t j1 = 0; j1 < cols; j1++)
tbl[i1][j1] = startVal++;

tbl[j1][i1] = startVal++; // probably transposed i & j
for(size_t i2 = 0; i2 < rows; i2++)
for(size_t j2 = 0; j2 < cols; j2++)
printf("Row: %d, Col: %d => %d\n",
i2, j2, tbl[i2][j2]);

.... again transposed i and j
 
C

CBFalconer

.... snip ...

[My apologies to C purists --- I am using the new operator instead
of malloc/calloc since I find its usage more intuitive]

There is no new operator in C.
.... snip ...

main()

main returns int. Say so.
{ .... snip ...

tbl = new (int**)[cols];

see above
for(size_t i = 0; i < rows; i++)
tbl = new (int *)[rows];


and see above. Try indenting your code or using a real newsreader.

In addition, do not crosspost without setting followups to one
group alone. F'ups set to the one group where it may be topical.
 
O

Old Wolf

I am having lots of trouble getting a simple program that initializs a
dynamically allocated 2D array to work. My 2D array is not getting
initialized properly, and additionally I am getting a "Null pointer
assignment" error. Kindly help.
#include <stdio.h>

#define ROWS 3
#define COLUMNS 5

main()
{
int **tbl;
size_t rows = ROWS;
size_t cols = COLUMNS;
int startVal = 2;

tbl = new (int**)[cols];

Bizarre that I had never seen someone do this until yesterday,
but now I've seen it twice (it came up in another thread).
What you mean is:

.. tbl = new int*[cols];

tbl is a pointer to pointer to int. So you must create
pointer(s) to int for it to point at.

The syntax you wrote is actually illegal (Comeau C++ would have
told you that). But some compilers parse it as:

.. tbl = (new (int**))[cols]

ie. creating a new pointer to pointer to int, and then
dereferencing it (causing undefined behaviour, probably
the cause of the errors you reported).

For more information, see the thread in comp.std.c++
titled "Strange new/new() problem".

for(size_t i = 0; i < rows; i++)
tbl = new (int *)[rows];


Ditto: tbl = new int[rows];

tbl is a pointer to int. It points to ints.
Obviously, trying to point it to a pointer-to-int will
get you into trouble.
for(size_t i1 = 0; i1 < rows; i1++)
for(size_t j1 = 0; j1 < cols; j1++)
tbl[i1][j1] = startVal++;

That should be tbl[j1][i1]

Remember that you created 'cols' pointers to int, and
each one points to a block of 'rows' ints.
for(size_t i2 = 0; i2 < rows; i2++)
for(size_t j2 = 0; j2 < cols; j2++)
printf("Row: %d, Col: %d => %d\n",
i2, j2, tbl[i2][j2]);
Ditto.

return 0;

You should delete[] all of the stuff you allocated.

You could have saved yourself a lot of trouble by using
a vector of vectors, instead of new and delete.
 
D

Dave Thompson

* (e-mail address removed):
[Cross-posted to C and C++ newsgroups, Not a Good Idea]

Please don't do that
(except where it is an issue of interest to practitioners of both).

Follow-up set to [comp.lang.c++].
Actually they weren't. (I've made the same mistake in the past, it's
not as convenient with Agent as one might like.) <G>

Must have 'int' return value type, both in C and C++.
In C99, and (any) C++.

tbl = new (int**)[cols];

tbl = new (int*)[cols];
No, that's also a (somewhat more obscure) mistake. It parses as
tbl = ( new (int*) ) [cols]
which allocates a single pointer, uninitialized, and tries to
subscript it. Except in (some versions of?) g++, which "fixes" it for
you. To be standard you want
tbl = new int * [cols];

<snip>

- David.Thompson1 at worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top