Is there a way to get the size of an Array the way sizeof() lets you get the size of an array?
|
Re: Arrays It is up to you to keep track of the "size" of the array, i.e. how many rows/columns you have used. |
Re: Arrays Tony_Goodman - Wed Apr 22 02:26:26 EDT 2009 |
Re: Arrays Doorsbert - Wed Apr 22 02:42:06 EDT 2009 int parseString (string toParse, Array &parsed) { ... } Pass it the string and a created array, get it to parse the string into the array and return the number of elements. This also gives you the option of returning 0 for 'no elements' or a negative number for an error. |
Re: Arrays Tony_Goodman - Wed Apr 22 02:26:26 EDT 2009 The interpreted languages like Perl and Python and Ruby all have datatypes that expand automatically to accomodate whatever you type, and they all let you determine the current size of the object. I think DXL is unique in deciding not to give users the capability to determine the current size. I would hope they reconsider this decision. |
Re: Arrays Tippers - Wed Apr 22 03:28:28 EDT 2009 Thanks Paul, I think you are right, it is better to return the int rather than the array. |
Re: Arrays Doorsbert - Wed Apr 22 13:31:46 EDT 2009 |
Re: Arrays void ::do (_y&, ArraySect__, void) ArrayDo ArraySect__ array(Array,int,int,int,int) mkArrayRef string get(Array,int,int,int) ArrayStringGet _x get(Array,int,int) ArrayGet void zeroArray(Array) ArrayZero void printCharArray(Array,Stream,int,int,int,int) ArrayPrintChar void putString(Array,string,int,int) ArrayPutString void put(Array,_x,int,int) ArrayPut void delete(Array) ArrayDelete Array create(int,int) ArrayCreate Testing, I see that you can indeed 'get' a location outside the current size of the array, no error and of course nothing is returned. the 'ArraySect__' stuff is curious, but that didn't work either. That looks like "for Contents in array(ary, 0, 0, NumX, Numy) do". I tried using that as well as 'cleverl' noError/lastError commands, but nothing worked. Yes, hard to believe they are that lenient. I think you can access location -1 -1, and if so I'd be tempted to reserve that location for the current sizes of the Array, and write functions that when data is inserted, it updates if needed the X and Y sizes in that location -1 , -1. A special 'get' function can check to make sure the user is not 'getting' outside the Array current bounds; not that it would do anything with that info.
|
Re: Arrays llandale - Wed Apr 22 15:25:53 EDT 2009
Basically, I'd made the indices into the array global, but forgotten to make the array global. So on the first pass, all worked well. Stuff got put in the array, starting from (0,0), and the indices got updated to point at the next free location. At the end of the function, the array got deleted. On the second pass through, the array got recreated, but now the indices are not starting at (0,0), they're starting at wherever they left off last time. No problem with putting things in the array, and no problem with getting things out of the array. It was only when I tried to use the variables that had been extracted from the array that DOORS crashed. That use could be anything: adding the values together, printing them, finding which was the largest. But DOORS only crashed on use, not on extraction (get). Fixed it by making the array global. No other changes to the code were required. Like I say, the code was wrong ... err ... the declarations were misplaced, but I didn't expect that kind of failure -- except, of course, this is DXL... ;) |
Re: Arrays llandale - Wed Apr 22 15:25:53 EDT 2009
@IIlandale thanks for your idea: how to go through the array. I helped me how to calculate the size. here you are: Array a = create(1,1)
put(a,"a",0,0) //size: 2Bytes --> 'a' and '\n' /*
// int get() returns the address of the item, if it zero there is not item any more
int sizeX = 4294967295 //2^32-1 integers are 32bit long in all plattforms after dxl manual for Contents in array(a, 0, 0, sizeX , sizeY) do{
iAddr = (int Contents) //it returns the address of the item if it zero, means end of array
|
Re: Arrays jszlatki - Mon Mar 24 07:01:26 EDT 2014 @IIlandale thanks for your idea: how to go through the array. I helped me how to calculate the size. here you are: Array a = create(1,1)
put(a,"a",0,0) //size: 2Bytes --> 'a' and '\n' /*
// int get() returns the address of the item, if it zero there is not item any more
int sizeX = 4294967295 //2^32-1 integers are 32bit long in all plattforms after dxl manual for Contents in array(a, 0, 0, sizeX , sizeY) do{
iAddr = (int Contents) //it returns the address of the item if it zero, means end of array
Wow. Now that really freaks me out ... And you really need much to freak me out, because normally I am the one who writes code like this. But your code just seems to be very wrong. It starts with your constants. Try: int a = 4294967295 print a // prints 2147483647 // because DXL uses signed integers and the interpreter will MIN/MAX out of bounds constants Then you need to know that the whole idea of the 'size' of an array is misleading. When you talk of 'size' what you really mean is the maximum index, that you set in the array. However setting an element at (0, 10) and one at (10,0) does not mean that (10,10) is already set. So the whole concept of 'sizeOf' is wrong for a two dimensional array (and that is probably the reason, why no function exists to actually read those values). You might want to know if an array item at some X/Y location is already set. Here you need to know that arrays are initialized with 0 bytes. That means, that you can of course test for integer 0 but that only works when you do not put integers in the Array: Array ar = create(10,10); put (ar, 0, 5,5) int a = (int (get (ar, 5,5))) // 0 we put it in int b = (int (get (ar, 1,1))) // 0 was initialized by default print "A = " a " B = " b "\n" // A = 0 B = 0 So that is also something that is not working in ALL cases. DXL is inconsistent here, because there is actually a value that would have been much better for initialization: -2023406815 (or -0x789abcdf) the value for an uninitialized value in DXL. If the DOORS developers would have put this value in the arrays for initialization it would have been much better, because we would get an error if we tried to read a value that has not been set and it would be easy to check:
Array createInitialized (int x, int y) {
Array ar = create(x,y)
// initialize the value with 'undefined'
int i, j;
for (i = 0; i < x; i++) for (j = 0; j < y; j++) put (ar, -0x789abcdf, i,j)
return ar
}
bool isSet(Array ar, int x, int y) {
return (-0x789abcdf != (int (get (ar, x, y))))
}
Array ar = createInitialized(10,10)
put (ar, 0, 1,1)
print "Is Set 0/0: " (isSet(ar, 0,0)) "\n"
print "Is Set 1/1: " (isSet(ar, 1,1)) "\n"
int b = (int get (ar, 0,0));
print b // uninitialized variable b
At least you know that you would never intentionally put an uninitialized variable to an array, so that would be fine, anyway it does not work when the array resizes. So the best way to handle this, is to simply create a DropIn Replacement for Array that 'remembers' what indices you put in:
struct SmartArray {}
SmartArray createSmartArray (int x, int y) {
DxlObject dx = new();
Array ar = create(x, y);
dx->"array" = ar
dx->"max_x" = -1;
dx->"max_y" = -1;
return (SmartArray (addr_ dx))
}
void put (SmartArray smar, _x valRef, int x, int y) {
DxlObject dx = ((addr_ smar) DxlObject);
Array ar = dx->"array";
int val = (int valRef);
put (ar, val, x, y);
// remember the last index we put in
int mx = dx->"max_x";
int my = dx->"max_y";
mx = mx >? x;
my = my >? y;
dx->"max_x" = mx;
dx->"max_y" = my;
}
int maxX(SmartArray smar) {
DxlObject dx = ((addr_ smar) DxlObject);
return (int (dx->"max_x"));
}
int maxY(SmartArray smar) {
DxlObject dx = ((addr_ smar) DxlObject);
return (int (dx->"max_y"));
}
Array array (SmartArray smar) {
return (Array ((addr_ smar) DxlObject)->"array");
}
// omitted delete here ...
SmartArray ar = createSmartArray(10,10);
put (ar, 5, 1, 1)
int a = (int (get (array ar, 1, 1)));
int b = (int (get (array ar, 5, 5)));
print "A = " a " B = " b "\n"
print "MAX: " (maxX ar) "/" (maxY ar) "\n"
put (ar, 5, 1, 4)
print "MAX after putting to 1/4: " (maxX ar) "/" (maxY ar) "\n"
put (ar, 5, 6, 2)
print "MAX after putting to 6/2: " (maxX ar) "/" (maxY ar) "\n"
The big advantage of this, is that you can just drop that SmartArray in your code as a library, change certain declarations of array into smart array and then a few compiler errors will tell you exactly where you need to make adaptions (the get function cant be rebuilt by native DXL). In any case based on an approach like that you can make the array even smarter if you chose to. Hopefully this lengthy discussion on Array is interesting to you (and/or someone else) ... Regards, Mathias |
Re: Arrays jszlatki - Mon Mar 24 07:01:26 EDT 2014 @IIlandale thanks for your idea: how to go through the array. I helped me how to calculate the size. here you are: Array a = create(1,1)
put(a,"a",0,0) //size: 2Bytes --> 'a' and '\n' /*
// int get() returns the address of the item, if it zero there is not item any more
int sizeX = 4294967295 //2^32-1 integers are 32bit long in all plattforms after dxl manual for Contents in array(a, 0, 0, sizeX , sizeY) do{
iAddr = (int Contents) //it returns the address of the item if it zero, means end of array
Your "Contents" loop does not look familiar. In any event it is wise to have a global integer associated with the "Array", something like
when you need a new row:
You thus always know the size of the array. -Louie |
Re: Arrays Mathias Mamsch - Mon Mar 24 14:17:24 EDT 2014 Wow. Now that really freaks me out ... And you really need much to freak me out, because normally I am the one who writes code like this. But your code just seems to be very wrong. It starts with your constants. Try: int a = 4294967295 print a // prints 2147483647 // because DXL uses signed integers and the interpreter will MIN/MAX out of bounds constants Then you need to know that the whole idea of the 'size' of an array is misleading. When you talk of 'size' what you really mean is the maximum index, that you set in the array. However setting an element at (0, 10) and one at (10,0) does not mean that (10,10) is already set. So the whole concept of 'sizeOf' is wrong for a two dimensional array (and that is probably the reason, why no function exists to actually read those values). You might want to know if an array item at some X/Y location is already set. Here you need to know that arrays are initialized with 0 bytes. That means, that you can of course test for integer 0 but that only works when you do not put integers in the Array: Array ar = create(10,10); put (ar, 0, 5,5) int a = (int (get (ar, 5,5))) // 0 we put it in int b = (int (get (ar, 1,1))) // 0 was initialized by default print "A = " a " B = " b "\n" // A = 0 B = 0 So that is also something that is not working in ALL cases. DXL is inconsistent here, because there is actually a value that would have been much better for initialization: -2023406815 (or -0x789abcdf) the value for an uninitialized value in DXL. If the DOORS developers would have put this value in the arrays for initialization it would have been much better, because we would get an error if we tried to read a value that has not been set and it would be easy to check:
Array createInitialized (int x, int y) {
Array ar = create(x,y)
// initialize the value with 'undefined'
int i, j;
for (i = 0; i < x; i++) for (j = 0; j < y; j++) put (ar, -0x789abcdf, i,j)
return ar
}
bool isSet(Array ar, int x, int y) {
return (-0x789abcdf != (int (get (ar, x, y))))
}
Array ar = createInitialized(10,10)
put (ar, 0, 1,1)
print "Is Set 0/0: " (isSet(ar, 0,0)) "\n"
print "Is Set 1/1: " (isSet(ar, 1,1)) "\n"
int b = (int get (ar, 0,0));
print b // uninitialized variable b
At least you know that you would never intentionally put an uninitialized variable to an array, so that would be fine, anyway it does not work when the array resizes. So the best way to handle this, is to simply create a DropIn Replacement for Array that 'remembers' what indices you put in:
struct SmartArray {}
SmartArray createSmartArray (int x, int y) {
DxlObject dx = new();
Array ar = create(x, y);
dx->"array" = ar
dx->"max_x" = -1;
dx->"max_y" = -1;
return (SmartArray (addr_ dx))
}
void put (SmartArray smar, _x valRef, int x, int y) {
DxlObject dx = ((addr_ smar) DxlObject);
Array ar = dx->"array";
int val = (int valRef);
put (ar, val, x, y);
// remember the last index we put in
int mx = dx->"max_x";
int my = dx->"max_y";
mx = mx >? x;
my = my >? y;
dx->"max_x" = mx;
dx->"max_y" = my;
}
int maxX(SmartArray smar) {
DxlObject dx = ((addr_ smar) DxlObject);
return (int (dx->"max_x"));
}
int maxY(SmartArray smar) {
DxlObject dx = ((addr_ smar) DxlObject);
return (int (dx->"max_y"));
}
Array array (SmartArray smar) {
return (Array ((addr_ smar) DxlObject)->"array");
}
// omitted delete here ...
SmartArray ar = createSmartArray(10,10);
put (ar, 5, 1, 1)
int a = (int (get (array ar, 1, 1)));
int b = (int (get (array ar, 5, 5)));
print "A = " a " B = " b "\n"
print "MAX: " (maxX ar) "/" (maxY ar) "\n"
put (ar, 5, 1, 4)
print "MAX after putting to 1/4: " (maxX ar) "/" (maxY ar) "\n"
put (ar, 5, 6, 2)
print "MAX after putting to 6/2: " (maxX ar) "/" (maxY ar) "\n"
The big advantage of this, is that you can just drop that SmartArray in your code as a library, change certain declarations of array into smart array and then a few compiler errors will tell you exactly where you need to make adaptions (the get function cant be rebuilt by native DXL). In any case based on an approach like that you can make the array even smarter if you chose to. Hopefully this lengthy discussion on Array is interesting to you (and/or someone else) ... Regards, Mathias Thanks for your feedback! You are right the init is bad. I only wanted to say with my post, what i realized, and I was happy about it :) I say voow too because of respect of your code. But after the manual the struct did not implemented, so I did not try it out.
Thanks, |
Re: Arrays llandale - Mon Mar 24 14:29:49 EDT 2014 Your "Contents" loop does not look familiar. In any event it is wise to have a global integer associated with the "Array", something like
when you need a new row:
You thus always know the size of the array. -Louie You mentioned in your post at: Apr 22, 2009 "That looks like "for Contents in array(ary, 0, 0, NumX, Numy) do"." I do not know how the Contents is declarated, and what kind of type does it have. You are right it is the easiest way to handle it. -Józsi |