From: TheDevil on
Hello,

See comments.

Or

See web link:

http://members.home.nl/hbthouppermans/VS2008Analysis/Index.htm

// *** Begin of Main.cpp ***

#include <stdio.h>

typedef char int8;
typedef short int int16;
typedef int int32;
typedef long long int64;

typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned long long uint64;

/*

13 april 2008

Back to School:

Lesson 5, Arrays, Static, Dynamic, Multi Dimesional.

Static 1D Array example
Dynamic 1D Array example

Static 2D Array example
Dynamic 2D Array example (Easy allocation/free, Hard usage)
Dynamic 2D Array example (Hard allocation/free, Easy usage)

Dynamic 3D Array example (Hard allocation/free, Easy usage)

Out of range indexes in static array have some detection in the form of
stack corruption runtime error. Pretty crappy.
Out of range indexes for dynamic array have no detection. Laughably lame.

Also for dynamic arrays programmer has to choose between:

1. Easy allocation/free and difficult usage.

or

2. Slightly difficult allocation/free and easy usage, probably with some
small pointer access overhead.

Choice 1 adds significant overhead for programmer trying to use/access the
array, he has to type a lot.
Choice 2 adds no overhead for programmer trying to use/access the array but
does involve some boring allocation and freeing code.

People suggesting templates for something as simple concept as arrays are
out of their mind, to introduce such complexities.

At least dynamic arrays are possible. I shall give it a subjective rating of
1 out of 10.

Conclusion:

Arrays in C/C++ insanely lame and can lead to hard to find bugs pretty
easily.

Preventing such bugs will require lots of overhead for the programmer who
would have to write lots of bound checking code or use some
crappy solution adding further complexities to his project. Possible
adventage could be compiler remains easy and therefore many compilers
for different systems/platforms.

Advice: Use solution/choice 2.

Platform test intel architecture 32.

Score: 1 out of 10

*/

int main()
{
printf("Program Started \n\n");

int8 vStaticArray[100]; // static array
int8 *vDynamicArray; // dynamic array
int8 vIndex;
int8 vJndex;
int8 vKndex;

// one dimensional static array, will be allocated on the stack. (Think
of it as temporarely limited memory)
for (vIndex=0; vIndex <= 99; vIndex++) // 100 would lead to stack
corrupted warning message.
{
vStaticArray[vIndex] = vIndex;
printf("vStaticArray[%d]: %d \n", vIndex, vStaticArray[vIndex] );
}

// one dimensional dynamic array, will be allocated on the heap. (Think
of it as main huge memory)
vDynamicArray = new int8[100];

for (vIndex=0; vIndex <= 99; vIndex++) // 100 would lead to BEEP, and
nothing else.
{
vDynamicArray[vIndex] = -vIndex;
printf("vDynamicArray[%d]: %d \n", vIndex, vDynamicArray[vIndex] );
}

delete vDynamicArray;

// two dimensional arrays, allocation simple, usage hard.

int8 vStaticArray2D[5][20];
int8 *vDynamicArray2D;

for (vIndex=0; vIndex<=4; vIndex++) // 5 would lead to stack corrupted
message after program shutdown... not too usefull.
{
for (vJndex=0; vJndex<=19; vJndex++)
{
vStaticArray2D[vIndex][vJndex] = (vIndex*20) + vJndex;
printf("vStaticArray2D[%d][%d]: %d \n", vIndex, vJndex,
vStaticArray2D[vIndex][vJndex] );
}
}

vDynamicArray2D = new int8[5 * 20];

for (vIndex=0; vIndex<=4; vIndex++)
{
for (vJndex=0; vJndex<=19; vJndex++)
{
vDynamicArray2D[vIndex*20 + vJndex] = (vIndex*20) + vJndex;
printf("vDynamicArray[%d][%d]: %d \n", vIndex, vJndex,
vDynamicArray2D[vIndex*20 + vJndex] );
}
}

delete vDynamicArray2D;

// two dimensional array, allocation hard, usage simple

int8 **vDynamicArray2DV2;

// allocation
vDynamicArray2DV2 = new int8* [5];

for (vIndex=0; vIndex <= 4; vIndex++)
{
vDynamicArray2DV2[vIndex] = new int8[20];
}

// access/usage
for (vIndex=0; vIndex<=4; vIndex++) // no range checking, 5 would cause
exception.
{
for (vJndex=0; vJndex<=19; vJndex++)
{
vDynamicArray2DV2[vIndex][vJndex] = (vIndex*20) + vJndex;
printf("vDynamicArray2DV2[%d][%d]: %d \n", vIndex, vJndex,
vDynamicArray2DV2[vIndex][vJndex] );
}
}

// free
for (vIndex=0; vIndex <= 4; vIndex++)
{
delete vDynamicArray2DV2[vIndex];
}

delete vDynamicArray2DV2;

// one last example showing a dynamic 3D array, simply extend the
previous code with an extra pointer and extra loop for extra dimension:

int8 ***vDynamicArray3D; // array will be: 2*5*10

// allocation
vDynamicArray3D = new int8** [2]; // first dimension

for (vIndex=0; vIndex <= 1; vIndex++)
{
vDynamicArray3D[vIndex] = new int8* [5]; // second dimension

for (vJndex=0; vJndex<=4; vJndex++)
{
vDynamicArray3D[vIndex][vJndex] = new int8[10]; // third
dimension
}
}

// access/usage
for (vIndex=0; vIndex<=1; vIndex++) // no range checking, 5 would cause
exception.
{
for (vJndex=0; vJndex<=4; vJndex++)
{
for (vKndex=0; vKndex<=9; vKndex++)
{
vDynamicArray3D[vIndex][vJndex][vKndex] = (vIndex*5*10) +
(vJndex*10) + vKndex;
printf("vDynamicArray3D[%d][%d][%d]: %d \n", vIndex, vJndex,
vKndex, vDynamicArray3D[vIndex][vJndex][vKndex] );
}
}
}

// free
for (vIndex=0; vIndex <= 1; vIndex++)
{
for (vJndex=0; vJndex<=4; vJndex++)
{
delete vDynamicArray3D[vIndex][vJndex]; // third dimension
}

delete vDynamicArray3D[vIndex]; // second dimension
}

delete vDynamicArray3D; // first dimension

printf("Program finished \n");
}

// *** End of Main.cpp ***

Bye,
The Devil.


From: Alf P. Steinbach on
* TheDevil:
>
> [raw] Arrays in C/C++ ... can lead to hard to find bugs pretty easily.

Yes, that's right.

As a novice, preferentially use std::vector, and use 'at(i)' rather than '[i]'.

When you gain more experience, look at the array classes in Boost and TR1.


Cheers, & hth.,

- Alf
From: Hal Vaughan on
Alf P. Steinbach wrote:

> * TheDevil:
>>
>> [raw] Arrays in C/C++ ... can lead to hard to find bugs pretty easily.
>
> Yes, that's right.
>
> As a novice, preferentially use std::vector, and use 'at(i)' rather than
> '[i]'.

Why use at(i) over [i]?

Hal
From: Alf P. Steinbach on
* Hal Vaughan:
> Alf P. Steinbach wrote:
>
>> * TheDevil:
>>> [raw] Arrays in C/C++ ... can lead to hard to find bugs pretty easily.
>> Yes, that's right.
>>
>> As a novice, preferentially use std::vector, and use 'at(i)' rather than
>> '[i]'.
>
> Why use at(i) over [i]?

Because it reacts to indexing errors by throwing an exception, instead of
silently producing an incorrect result or trashing some memory area.

In other words, it provides guaranteed bounds-checking.

So it's much easier to detect those nefarious bugs.


Cheers, & hth.,

- Alf