NXC: program hangs up when resizing arrays

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

NXC: program hangs up when resizing arrays

Post by HaWe »

hey,
maybe another NXC bug now when using ArrayInit and ArrayBuild for risizing arrays of string -
the program blocks completely,
the BCC program window freezes,
the NXT screen shows "testprogram running"
the NXT is clicking (like if in SAMBA mode):

Code: Select all

// Array Resize

#define ArrRze(&_array_[], _temp_[], _newsize_)  {  \
   int _oldlen_ = ArrayLen(_array_);                   \
   if(_newsize_ > _oldlen_) {                          \
     int _diffsize_ = _newsize_ - _oldlen_;            \
     ArrayInit (_temp_, 0, _diffsize_ );               \
     ArrayBuild(_array_, _array_, _temp_);             \
   }                                                   \
   else                                                \
   if(_newsize_ < _oldlen_) {                          \
     ArraySubset(_array_, _array_, 0, _newsize_);      \
   }                                                   \
}

#define ArrayResize(a,b)  ArrRze(a,a,b)


string array1[2];

task main()
{
   array1[0] = "ok1";
   array1[1] = "ok2";

   ArrayResize(array1, 4);  //

   TextOut(0, 48, array1[0]);     // ok1
   TextOut(0, 40, array1[1]);     // ok2

   TextOut(0, 32, array1[2]);     // ""
   TextOut(0, 24, array1[3]);     // ""

   Wait(10000);
}
only removing the batteries can reboot the brick.
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: program hangs up when resizing arrays

Post by HaWe »

another issue now when resizing arrays of int -

no program hang-up or block but it produces wrong results after resizing:

The array cells get muddled up and show values of fantasy and imagination instead of the (expected) initialized values:
The previously assigned values (101, 102) are overwritten to zero and the expanded cells show (big) negative values instead of zero:

Code: Select all

#define ArrRze(&_array_[], _temp_[], _newsize_)  {  \
   int _oldlen_ = ArrayLen(_array_);                   \
   if(_newsize_ > _oldlen_) {                          \
     int _diffsize_ = _newsize_ - _oldlen_;            \
     ArrayInit (_temp_, 0, _diffsize_ );               \
     ArrayBuild(_array_, _array_, _temp_);             \
   }                                                   \
   else                                                \
   if(_newsize_ < _oldlen_) {                          \
     ArraySubset(_array_, _array_, 0, _newsize_);      \
   }                                                   \
}

#define ArrayResize(a,b)  ArrRze(a,a,b)


int  array1[2];

#define CLREOL DRAW_OPT_CLEAR_EOL

task main()
{
   array1[0] = 101;
   array1[1] = 102;

   ArrayResize(array1,4);                // shows:

   NumOut(0, 48, array1[0], CLREOL);     // 0   instead of 101
   NumOut(0, 40, array1[1], CLREOL);     // 0   instead of 102

   NumOut(0, 32, array1[2], CLREOL);     //  -16657 instead of 0
   NumOut(0, 24, array1[3], CLREOL);     //  -8531  instead of 0

   Wait(10000);
}
Using a global temporary array as a buffer instead, the old values stay correct as assigned before (101, 102) but nevertheless the new expanded cells show the same irrational values instead of zero.

Code: Select all

#define ArrRze(&_array_[], _temp_[], _newsize_)  {  \
   int _oldlen_ = ArrayLen(_array_);                   \
   if(_newsize_ > _oldlen_) {                          \
     int _diffsize_ = _newsize_ - _oldlen_;            \
     ArrayInit (_temp_, 0, _diffsize_ );               \
     ArrayBuild(_array_, _array_, _temp_);             \
   }                                                   \
   else                                                \
   if(_newsize_ < _oldlen_) {                          \
     ArraySubset(_array_, _array_, 0, _newsize_);      \
   }                                                   \
}

// #define ArrayResize(a,b)  ArrRze(a,a,b)


int  array1[2], temp[];

#define CLREOL DRAW_OPT_CLEAR_EOL

task main()
{
   array1[0] = 101;
   array1[1] = 102;

   ArrRze(array1, temp, 4);                // shows:

   NumOut(0, 48, array1[0], CLREOL);     //  101  ok
   NumOut(0, 40, array1[1], CLREOL);     //  102  ok

   NumOut(0, 32, array1[2], CLREOL);     //  -16657 instead of 0
   NumOut(0, 24, array1[3], CLREOL);     //  -8531  instead of 0

   Wait(10000);
}
supposed to be a NXC bug... :roll:
mattallen37
Posts: 1818
Joined: 02 Oct 2010, 02:19
Location: Michigan USA
Contact:

Re: NXC: program hangs up when resizing arrays

Post by mattallen37 »

Try stripping the program down to the point that it's only a couple lines, but still demonstrates the problem (put everything in the main task, rather than using a function and a macro wrapper to that function). Usually I can find the problem by doing so, and even if not, it makes it easier for other people to debug it.

I have a feeling it has to do with the way you are passing the array through the macro, into the function, back out to the macro, and then back into your program. I suggest you try an alternative way of doing this, and see if it improves performance.
Matt
http://mattallen37.wordpress.com/

I'm all for gun control... that's why I use both hands when shooting ;)
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: program hangs up when resizing arrays

Post by HaWe »

thank you, Matt,
originally it's meant for a library array function,
but written top/down it's all the same:

Code: Select all

int  array1[2], temp[];

#define CLREOL DRAW_OPT_CLEAR_EOL

task main()
{
   array1[0] = 101;
   array1[1] = 102;


   int _oldlen_ = ArrayLen(array1);
   int _newsize_ = 4;
   
   if(_newsize_ > _oldlen_) {
     int _diffsize_ = _newsize_ - _oldlen_;
     ArrayInit (temp, 0, _diffsize_ );
     ArrayBuild(array1, array1, temp);
   }
   else
   if(_newsize_ < _oldlen_) {
     ArraySubset(array1, array1, 0, _newsize_);
   }
   // ArrRze(array1, temp, 4);                // shows:

   NumOut(0, 48, array1[0], CLREOL);     //  101  ok
   NumOut(0, 40, array1[1], CLREOL);     //  102  ok

   NumOut(0, 32, array1[2], CLREOL);     //  -16657 instead of 0
   NumOut(0, 24, array1[3], CLREOL);     //  -8531  instead of 0

   Wait(10000);
}
interesting side effect:
if I choose int _newsize_ = 2 then it ends with a file error -1 :shock:
mattallen37
Posts: 1818
Joined: 02 Oct 2010, 02:19
Location: Michigan USA
Contact:

Re: NXC: program hangs up when resizing arrays

Post by mattallen37 »

What if you keep stripping lines out? Try adding some debugging (NumOut usually works well).

I'm pretty busy, but I might be able to look into it a bit. I'll let you know if I happen to find anything.
Matt
http://mattallen37.wordpress.com/

I'm all for gun control... that's why I use both hands when shooting ;)
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: program hangs up when resizing arrays

Post by HaWe »

there are no lines to be stripped out.

it's simple as it could be:

- define an array[2]
- define a new size
- decide what to do either if new size is larger or smaller than old size
- do it!
- show it!

I guess there are API function issues concerning ArrayBuild and ArrayInit.
mattallen37
Posts: 1818
Joined: 02 Oct 2010, 02:19
Location: Michigan USA
Contact:

Re: NXC: program hangs up when resizing arrays

Post by mattallen37 »

ArrayBuild doesn't seem to like the destination to be the same as any of the sources (which is likely a bug).

This seems to work fine:

Code: Select all

#define ArrayResize(& Array[], NewSize){     \
  int OldSize = ArrayLen(Array);             \
  if(NewSize > OldSize){                     \
    int DiffSize = NewSize - OldSize;        \
    int Array_Temp[];                        \
    ArrayInit(Array_Temp, 0, DiffSize);      \
    int Array_In[];                          \
    ArraySubset(Array_In, Array, 0, NA);     \
    ArrayBuild(Array, Array_In, Array_Temp); \
  }                                          \
  else if(NewSize < OldSize){                \
    ArraySubset(Array, Array, 0, NewSize);   \
  }                                          \
}
When NewSize is greater than the length of the input array, it creates Array_Temp with the number of elements to make up the difference, it copies Array into Array_In, and it builds Array from Array_In and Array_Temp.
Matt
http://mattallen37.wordpress.com/

I'm all for gun control... that's why I use both hands when shooting ;)
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: NXC: program hangs up when resizing arrays

Post by afanofosc »

ArrayBuild cannot use the output as an input, which makes sense and is not a bug. The output array is reallocated by the firmware before data is copied into it and that replaces the pointer to the array contents in memory with the newly allocated address so it can't read from the original source array anymore.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: program hangs up when resizing arrays

Post by HaWe »

thanks to both of you!
I'll now have to try the following code - to keep the array variable type universal, the original array will have to be passed 3 times to the macro.
(can't test it for the moment but will report):

Code: Select all

#define ArrRze(&_array_[], _arrold_[], _temp_[], _newsize_)  {  \
   int _oldlen_ = ArrayLen(_arrold_);                  \
   if(_newsize_ > _oldlen_) {                          \
     int _diffsize_ = _newsize_ - _oldlen_;            \
     ArrayInit (_temp_, 0, _diffsize_ );               \
     ArrayBuild(_array_, _arrold_, _temp_);            \
   }                                                   \
   else                                                \
   if(_newsize_ < _oldlen_) {                          \
     ArraySubset(_array_, _arrold_, 0, _newsize_);     \
   }                                                   \          
  ArrayInit (_temp_, 0, 0 );                           \
  ArrayInit (_arrold_, 0, 0 );                         \
}                                                        

#define ArrayResize(a,b)  ArrRze(a,a,a,b)


int array1[2];

task main()
{
   array1[0] = 101;
   array1[1] = 102;

   ArrayResize(array1, 5);  //

   NumOut(0, 48, array1[0]);     //
   NumOut(0, 40, array1[1]);     //

   NumOut(0, 32, array1[2]);     //
   NumOut(0, 24, array1[3]);     //

   Wait(10000);
}
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: program hangs up when resizing arrays

Post by HaWe »

trying the code above I get file error -1

if I delete the last both ArrayInits I still get faulty results:
0
0
0
-8531

instead of
101
102
0
0

Code: Select all

#define ArrRze(&_array_[], _arrold_[], _temp_[], _newsize_)  {  \
   int _oldlen_ = ArrayLen(_arrold_);                  \
   if(_newsize_ > _oldlen_) {                          \
     int _diffsize_ = _newsize_ - _oldlen_;            \
     ArrayInit (_temp_, 0, _diffsize_ );               \
     ArrayBuild(_array_, _arrold_, _temp_);            \
   }                                                   \
   else                                                \
   if(_newsize_ < _oldlen_) {                          \
     ArraySubset(_array_, _arrold_, 0, _newsize_);     \
   }                                                   \
}


#define ArrayResize(a,b)  ArrRze(a,a,a,b)


int array1[2];

task main()
{
   array1[0] = 101;
   array1[1] = 102;

   ArrayResize(array1, 5);  //  shows

   NumOut(0, 48, array1[0]);     //   0
   NumOut(0, 40, array1[1]);     //   0

   NumOut(0, 32, array1[2]);     //   0
   NumOut(0, 24, array1[3]);     //   -8531

   Wait(10000);
}
There must be an unexpected NXC bug - or two...
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest