www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Arrays

reply Olli Aalto <oaalto gmail.com> writes:
Hi!

I've been playing with arrays lately. Static arrays, 2/3/4 dimensional 
arrays and dynamic arrays.

First I'd like to ask if it's safe to do this:

int[] getIntArrayWithLengthOf2()
{
	int[] array = new int[2];
	array[] = 2;
	return array;
}

some scope
{
	int[2] array2 = getIntArrayWithLengthOf2();
}

It seem to work, but what about memory? How's it handled? Do I need to 
delete it if I don't want the GC take care of it? Or does the array2 go 
out of scope when leaving the "some scope"?
What if the array2 is a class field?

I'm asking this because I'm working with static arrays mostly, but as I 
can't return them from functions I need to return a dynamic array 
instead. Then I'm assigning it to a static array. Is this wise?

Thanks,

O.
Jan 10 2007
next sibling parent Olli Aalto <oaalto gmail.com> writes:
int[2] intArray = [ 1, 2 ];
int[2] intArray2 = [ 1, 2 ];

assert(intArray == intArray2);  // OK

But...

First:

int[2][2] intMatrix = [ [ 2, 2 ], [ 2, 2 ] ];
This wont compile if it's inside for example unittest block.

I have to declare is either static or in the module scope.

Second:

static int[2][2] intMatrix = [ [ 2, 2 ], [ 2, 2 ] ];
static int[2][2] intMatrix2 = [ [ 2, 2 ], [ 2, 2 ] ];

assert(intMatrix == intMatrix2); // Error: Access Violation

Also I get the access violation if I try to print out the matrix:
std.stdio.writefln(intMatrix);

Any ideas what's going on?

Thanks,

O.
Jan 10 2007
prev sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Olli Aalto wrote:
 Hi!
 
 I've been playing with arrays lately. Static arrays, 2/3/4 dimensional 
 arrays and dynamic arrays.
 
 First I'd like to ask if it's safe to do this:
 
 int[] getIntArrayWithLengthOf2()
 {
     int[] array = new int[2];
     array[] = 2;
     return array;
 }
 
 some scope
 {
     int[2] array2 = getIntArrayWithLengthOf2();
 }
 
 It seem to work, but what about memory? How's it handled? Do I need to 
 delete it if I don't want the GC take care of it?

You have declared an int[2], that is a static array, so it is allocated on the stack. What happens is that getIntArrayWithLengthOf2 allocates an array on the heap, and then its contents are copied into array2. The array allocated on the heap becomes unreachable, and so will be picked up by the GC the next time it runs, even if control is still within some scope. The copy in array2, OTOH, will persist until the end of the scope. If OTOH you declared int[] array2 = getIntArrayWithLengthOf2(); then array2 is a dynamic array. Assignment is then by reference, and so array2 points into the memory allocated on the heap by getIntArrayWithLengthOf2. The GC will not free the heap-allocated memory until array2 goes out of scope or is assigned something else. Even then, it will only free it if no other reachable reference to it exists. Stewart.
Jan 10 2007
parent reply Olli Aalto <oaalto gmail.com> writes:
Stewart Gordon wrote:
 Olli Aalto wrote:
 Hi!

 I've been playing with arrays lately. Static arrays, 2/3/4 dimensional 
 arrays and dynamic arrays.

 First I'd like to ask if it's safe to do this:

 int[] getIntArrayWithLengthOf2()
 {
     int[] array = new int[2];
     array[] = 2;
     return array;
 }

 some scope
 {
     int[2] array2 = getIntArrayWithLengthOf2();
 }

 It seem to work, but what about memory? How's it handled? Do I need to 
 delete it if I don't want the GC take care of it?

You have declared an int[2], that is a static array, so it is allocated on the stack. What happens is that getIntArrayWithLengthOf2 allocates an array on the heap, and then its contents are copied into array2. The array allocated on the heap becomes unreachable, and so will be picked up by the GC the next time it runs, even if control is still within some scope. The copy in array2, OTOH, will persist until the end of the scope. If OTOH you declared int[] array2 = getIntArrayWithLengthOf2(); then array2 is a dynamic array. Assignment is then by reference, and so array2 points into the memory allocated on the heap by getIntArrayWithLengthOf2. The GC will not free the heap-allocated memory until array2 goes out of scope or is assigned something else. Even then, it will only free it if no other reachable reference to it exists.

Thanks for the explanation. I'm still wondering why I can't return a static array from a function. I know it will be out of scope, but couldn't the contents be copied like in the above example? O.
Jan 11 2007
parent Daniel Keep <daniel.keep+lists gmail.com> writes:
Olli Aalto wrote:
 Stewart Gordon wrote:
 
 Olli Aalto wrote:

 Hi!

 I've been playing with arrays lately. Static arrays, 2/3/4 
 dimensional arrays and dynamic arrays.

 First I'd like to ask if it's safe to do this:

 int[] getIntArrayWithLengthOf2()
 {
     int[] array = new int[2];
     array[] = 2;
     return array;
 }

 some scope
 {
     int[2] array2 = getIntArrayWithLengthOf2();
 }

 It seem to work, but what about memory? How's it handled? Do I need 
 to delete it if I don't want the GC take care of it?

<snip> You have declared an int[2], that is a static array, so it is allocated on the stack. What happens is that getIntArrayWithLengthOf2 allocates an array on the heap, and then its contents are copied into array2. The array allocated on the heap becomes unreachable, and so will be picked up by the GC the next time it runs, even if control is still within some scope. The copy in array2, OTOH, will persist until the end of the scope. If OTOH you declared int[] array2 = getIntArrayWithLengthOf2(); then array2 is a dynamic array. Assignment is then by reference, and so array2 points into the memory allocated on the heap by getIntArrayWithLengthOf2. The GC will not free the heap-allocated memory until array2 goes out of scope or is assigned something else. Even then, it will only free it if no other reachable reference to it exists.

Thanks for the explanation. I'm still wondering why I can't return a static array from a function. I know it will be out of scope, but couldn't the contents be copied like in the above example? O.

It's a somewhat round-about way of doing it, but you could always try something like this: struct StaticArray(T, uint n) { T[n] data; } StaticArray!(int,2) getIntArrayWithLengthOf2() { StaticArray!(int,2) result; result.data[] = 2; return result; } I'm not 100% sure if you could use opCast to make the code a bit easier on the user end, or other template tricks you could apply. Hope this helps some, -- Daniel
Jan 14 2007