472,119 Members | 1,003 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,119 software developers and data experts.

2D arrays question

csx
Hi everyone!

two quick questions relating to arrays.

Q1,
Is it possible to re-assign array elements?

int array[2][2] = {{2,4}, {4,5}};

array[1][1] = {2,3}

just causes compiler errors! Do I have to assign at the beginning?

Q2,
My other 'main' question relates to 2-Dimensional arrays.

I need to create the size of my 2D array at run time. I have a couple of
functions that provide the dimensions I need. I need to call the function
like:

two_dimensional_array(maxRows, numLeafs)

but then, assign the values after, hence my first question. Can values be
asigned after?

Here is the code I currently have? Is this a good implementation? Any
suggestions would be much appreciated.

int ** myArray = 0; // in C++ 0==NULL

void two_dimensional_array(int rows, int cols)
{
int Rows, Cols;
if (myArray != NULL) {
for (int i = 0; i < Rows; i++) {
myArray[i] = new int[Cols];
}
}
}

int _tmain(int argc, _TCHAR* argv[])
{
myArray = new *int[Rows];
return 0;
}
Jul 19 '05 #1
7 11648
"csx" <cs*@ms.com> wrote in message
news:bl**********@sparta.btinternet.com...
Hi everyone!

two quick questions relating to arrays.

Q1,
Is it possible to re-assign array elements?
Yes, individually.

int array[2][2] = {{2,4}, {4,5}};

array[1][1] = {2,3}
Invalid syntax.

Also, array[1][1] denotes a single type 'int' object.
How do you expect to store two values in a single object?

Guessing at which elements you really want to change:

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

just causes compiler errors! Do I have to assign at the beginning?
You must assign each element's value individually.
If your values form an appropriate 'pattern' this
can often be done in a loop.
Q2,
My other 'main' question relates to 2-Dimensional arrays.

I need to create the size of my 2D array at run time. I have a couple of
functions that provide the dimensions I need. I need to call the function
like:

two_dimensional_array(maxRows, numLeafs)

but then, assign the values after, hence my first question. Can values be
asigned after?
Yes.
Here is the code I currently have? Is this a good implementation? Any
suggestions would be much appreciated.

int ** myArray = 0; // in C++ 0==NULL
This is not an array, it's a pointer. It does
not point to any storage you can use.
You must allocate some memory and assign its
address to the pointer. I see you tried to
below, but fall short.


void two_dimensional_array(int rows, int cols)
That's not a very desriptive name. I'd call it
e.g. 'load2darray', 'populate2darray' or something like that.
Also note that you never call this function in the code
you've posted.
{
int Rows, Cols;
Array dimensions should be stored in type 'size_t'
Type 'int' won't necessarily be able to represent
all possible array index values. 'size_t' is
guaranteed to be able to.

if (myArray != NULL) {
for (int i = 0; i < Rows; i++) {
myArray[i] = new int[Cols];
}
}
}

int _tmain(int argc, _TCHAR* argv[])
int main(int argc, char *argv[]) {

No "Windows-isms" allowed here.
myArray = new *int[Rows];
Invalid syntax.

myArray = new int*[Rows];

But this only allocates storage for 'Rows' pointers.
There's still no storage for them to point to.
return 0;
}


The difficulty so many have with arrays is one reason
for the invention of standard library containers such
as std::vector.

I recommend you use containers instead of arrays in
C++ programs, unless there's a compelling reaons to
do otherwise (e.g. interface with C or existing,
nonmodifiable code).

std::vector<std::vector> > arr2d;

-Can do anything an array can do, and more.
-Does all the memory management for you.
-Is 'flexible' -- will grow or shrink its size as needed.
-Carries its size with it, no need to pass an extra 'size'
to functions as with arrays.

If you insist upon using arrays, perhaps you'll find
useful an example in C I posted to comp.lang.c today. Look
for my name as author of a post in a thread entitled
"Re: How to free allocated memory?"

It uses the C functions 'malloc()' and 'free()' for
memory management, but you should be able to drop in
new[] and delete[] in their place -- you *must* do this
if you're creating arrays of types which have ctors/dtors,
or they won't get called.

But if you don't have to, don't use arrays. Use containers.
Really.

HTH,
-Mike
Jul 19 '05 #2
csx wrote:
Hi everyone!

two quick questions relating to arrays.

Q1,
Is it possible to re-assign array elements?
Of course, unless the elements are 'const'.

int array[2][2] = {{2,4}, {4,5}};

array[1][1] = {2,3}

just causes compiler errors! Do I have to assign at the beginning?
Of course it's an error. The {...} syntax is only for initializers. Why
are you trying to give one element two values anyway?

array[1][1] = 3;

Q2,
My other 'main' question relates to 2-Dimensional arrays.

I need to create the size of my 2D array at run time.
Say no more.

http://www.parashift.com/c++-faq-lit...html#faq-16.19
http://www.parashift.com/c++-faq-lit...html#faq-16.15

The short answer is: Use std::vector.
I have a couple of
functions that provide the dimensions I need. I need to call the function
like:

two_dimensional_array(maxRows, numLeafs)

but then, assign the values after, hence my first question. Can values be
asigned after?

Here is the code I currently have? Is this a good implementation? Any
suggestions would be much appreciated.

int ** myArray = 0; // in C++ 0==NULL
Evil global variable.

void two_dimensional_array(int rows, int cols)
{
int Rows, Cols;
if (myArray != NULL) {
for (int i = 0; i < Rows; i++) {
myArray[i] = new int[Cols];
}
}
}
Why wouldn't you have this function return the pointer rather than
acting on an evil global variable?

Besides that, it seems really broken. Why doesn't it allocate the
initial int* array? Why does it indiscriminately overwrite the elements
of the array that myArray points to? What if those pointers already
pointed to dynamic memory?

int _tmain(int argc, _TCHAR* argv[])
_tmain is a reserved identifier in the global namespace (as are all
identifiers beginning with an underscore followed by a lower-case
letter). That means you may not use it as a name in the global
namespace. Also, _TCHAR is reserved in all contexts (as are all
identifiers beginning with an underscore followed by an upper-case
letter or another underscore), and you may not use it at all. In
general, avoid identifier names beginning with an underscore. (And try
posting *standard* C++ code when you post here.)
{
myArray = new *int[Rows];
return 0;
Uh, memory leak? What exactly was this supposed to demonstrate?
}


-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Jul 19 '05 #3
Mike Wahler wrote:


The difficulty so many have with arrays is one reason
for the invention of standard library containers such
as std::vector.

I recommend you use containers instead of arrays in
C++ programs, unless there's a compelling reaons to
do otherwise (e.g. interface with C or existing,
nonmodifiable code).

std::vector<std::vector> > arr2d;


std::vector<std::vector<int> > arr2d;

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Jul 19 '05 #4
"Kevin Goodsell" <us*********************@neverbox.com> wrote in message
news:7R*****************@newsread3.news.pas.earthl ink.net...
Mike Wahler wrote:
std::vector<std::vector> > arr2d;


std::vector<std::vector<int> > arr2d;


Oops, yes, thanks.

-Mike
Jul 19 '05 #5
csx
Hi, and thanks so much! Ive looked at your array example in C, and it has
been very helpful.
However, there were a couple of things. In this function:

double **alloc2d(size_t rows, size_t cols)
{
double **result;
size_t row = 0;
size_t col = 0;
if(result = malloc(rows * sizeof *result))
{
if(*result = malloc(rows * cols * sizeof **result)
for(row = 1; row < rows; ++row)
result[row] = *result + row * cols;
else
{
free(result);
result = NULL;
}
}
return result;
}
There is a problem on the lines
if(result = malloc(rows * sizeof *result))
if(*result = malloc(rows * cols * sizeof **result)

There are the errors:
error C2440: '=' : cannot convert from 'void *' to 'double ** '
error C2440: '=' : cannot convert from 'void *' to 'double *'

Not sure how to fix these, can anyone provide advise?
Many 'Thanks' in advance!!
Jul 19 '05 #6
"csx" <cs*@ms.com> wrote in message
news:bl**********@hercules.btinternet.com...
Hi, and thanks so much! Ive looked at your array example in C, and it has
been very helpful.
First note that C is not C++. They look very similar
in syntax, the the semantics are different in many
cases. You've just discovered one example of this.

I referred you to that C code for ideas, not
as a 'drop in' C++ solution to your questions.

However, that code I wrote can be made valid C++ with
a simple 'fix'. (actually I'd call it a 'hack').

Or you can configure your compiler to compile
C instead of C++).

See below.
However, there were a couple of things. In this function:

double **alloc2d(size_t rows, size_t cols)
{
double **result;
size_t row = 0;
size_t col = 0;
if(result = malloc(rows * sizeof *result))
{
if(*result = malloc(rows * cols * sizeof **result)
for(row = 1; row < rows; ++row)
result[row] = *result + row * cols;
else
{
free(result);
result = NULL;
}
}
return result;
}
There is a problem on the lines
if(result = malloc(rows * sizeof *result))
if(*result = malloc(rows * cols * sizeof **result)

There are the errors:
error C2440: '=' : cannot convert from 'void *' to 'double ** '
error C2440: '=' : cannot convert from 'void *' to 'double *'
Those are indeed errors in C++, but not in C.
Not sure how to fix these, can anyone provide advise?
Many 'Thanks' in advance!!


Remember what I wrote:

"It uses the C functions 'malloc()' and 'free()' for
memory management, but you should be able to drop in
new[] and delete[] in their place -- you *must* do this
if you're creating arrays of types which have ctors/dtors,
or they won't get called."

I forgot to add "if you use 'malloc()' you'll need to
cast the return value to the target type"

C allows the conversion from/to 'void*' and any other
pointer type without a cast. But C++ requires a cast:

/* hack: */
if(result = (double**)malloc(rows * sizeof *result))
if(*result = (double*)malloc(rows * cols * sizeof **result)

I also wrote:
"But if you don't have to, don't use arrays. Use containers.
Really."

And I still stand by that advice.

-Mike
Jul 19 '05 #7
csx
Thanks Mike!
Jul 19 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

12 posts views Thread by Samee Zahur | last post: by
9 posts views Thread by Charles Banas | last post: by
1 post views Thread by rir3760 | last post: by
27 posts views Thread by jacob navia | last post: by
3 posts views Thread by James dean | last post: by
41 posts views Thread by Rene Nyffenegger | last post: by
16 posts views Thread by mike3 | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.