Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Problems initializing a dynamically allocated 2D array

26 views
Skip to first unread message

masood...@lycos.com

unread,
Jan 30, 2005, 9:51:05 AM1/30/05
to
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[i] = 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;
}

Alf P. Steinbach

unread,
Jan 30, 2005, 10:15:20 AM1/30/05
to
* masood...@lycos.com:
> [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++].


* masood...@lycos.com:


> 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;


> main()

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[i] = new (int *)[rows];

tbl[i] = 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: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

Gianni Mariani

unread,
Jan 30, 2005, 10:52:27 AM1/30/05
to
masood...@lycos.com wrote:
> 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[i] = new (int *)[rows];

tbl[i] = 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

> return 0;
> }
>

CBFalconer

unread,
Jan 30, 2005, 11:03:44 AM1/30/05
to
masood...@lycos.com wrote:
>
... 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[i] = 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.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson


Dave Thompson

unread,
Feb 7, 2005, 1:55:38 AM2/7/05
to
On Sun, 30 Jan 2005 15:15:20 GMT, al...@start.no (Alf P. Steinbach)
wrote:

> * masood...@lycos.com:
> > [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>

<snip>


> > main()
>
> Must have 'int' return value type, both in C and C++.
>

In C99, and (any) C++.

<snip>


> > 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

0 new messages