MATLAB: Matrix Index is out of range for deletion - arrays

I have this function where I use an array as a FIFO queue (i.e., put elements in it and process them using a first-in first-served approach). In particular, I call this array a MsgQueue as it holds messages.
The MsgQueue is used when a new msg is sent (event), which triggers the execution of the handleMsgSent() method, which I show next
function handleMsgSent(this, msg)
this.MsgQueue = [this.MsgQueue msg];
while(numel(this.MsgQueue) > 0)
m = this.MsgQueue(1);
this.MsgQueue = this.MsgQueue(2:end); % <----- OPTION A
% DO WHATEVER WITH THE MESSAGE
%this.MsgQueue(1) = []; % <------ OPTION B
end
end
As you can see I have marked the code with OPTION A and OPTION B comment. So, the point is option B ends up with the "Matrix Index is out of range for deletion" error while option A works (apparently) perfectly fine, with no errors.
Can anyone help me to understand the difference? Well, I understand that option A is not deleting anything but just "discarding" the first element of the array but, why does option B fails in deleting if there is at least one element in MsgQueue?

For an empty array, end is 0. If you check the documentation for the colon operator, for start>end it returns an empty array. Thus, the first option deletes noting in some cases while the second option always indexes the second element.

After debugging my code I seem to have realised of the reason. In my code there is a comment:
% DO WHATEVER WITH THE MESSAGE
The problem was that at this point I was invoking another method that triggered new messages to be sent and thus entering the handleMsgSent() method again. Thus, when I modify the MsgQueue before that I have no problems but when I do it afterwards I get into trouble.

Related

What does &array[element] means and why?

I was coding in MPI using C. I don't understand how the MPI_Send() works or if maybe &array[element] works.
MPI_Send(&array[element],element_left,MPI_INT,i,0,MPI_COMM_WORLD);
here array[]={1,2,3,4,5,6,7,8,9,10} and element = 6 and element_left = 4. I understand array[element]=array[6]=7 but why this function picks 7,8,9,10? I know it will pick 4 elements from the array but why do we need & here and by only giving starting entry array[6] how is this function able to pick the next 3 as well?
I thought I have to add one after another using a for loop or something, but when I searched something on Google I got this code and after going through so much I still didn't understand. Please help me understand the backwardness of this code.
&array[element] is the same expression as array + element and means the address of the elementth element of the array array.
The function you call wants this address as the first argument, and takes the number of elements to process as the second argument.
Most MPI routines take a trio of arguments:
address of buffer
count of elements
datatype of elements
So by &array[element],element_left,MPI_INT you specify the elements element as the start of the buffer, and then you take element_left many integers to send. Kinda strange that you name the count element_left which is more like a name for an index, but that's what happens.

initialize an array with loop in Eiffel

I'm trying so hard to initialize an array or arrayList of strings from a file while using a loop, but every function I'm using- put/enter/force nothing seems to work. the array time after time got filled with the last string I read even though I'm accessing a specific index that I increasing every iteration.
(I tried to add regular constant string and it worked well, I don't understand the difference.
Thanks to everyone who would help.
tArray:ARRAY[STRING] -- declaring
create tArray.make_empty
readingFile() --function
local
k:INTEGER_32
do
from k:=0
until curFile.end_of_file
loop
curFile.read_line
curLine:=curFile.last_string
tArray.force (curLine, k)
--tArray.put(curLine, k)
--tArray.enter (curLine, k)
--tArray.at (k):=curLine
--tArray.force ("sara", k+1)
k:=k+1
end
end
The feature read_line does not create a new string object every time, but rather reuses the last one. In other words, last_string always refers to the same object. The solution is to use a clone of the object associated with last_string at every iteration:
curLine := curFile.last_string.twin

Strange Array behavior using push and splice

I have a page full of mc_card's and want the user to choose which ones to add to their deck.
click a card and cardChosen = true for that card;
click again and cardChosen = false;
This works fine.
Upon choosing a card the frame number is stored in an array. Each card is on a separate frame and there are no duplicates.
Main.cardArray.push(this.currentFrame);
Upon clicking it again, I want to remove that frame number from the array:
Main.cardArray.splice(this.currentFrame, 1);
After I splice the array, I trace it, and I'm getting weird results. Sometimes it works like I would expect, but then it removes the wrong numbers and sometimes doesnt remove them at all.
splice() works in another way, that you try to use.
Here is statement:
splice(startIndex:int, deleteCount:uint, ... values):Array
So, first arg - start index in array to delete, and second arg - how much elements must be deleted from the start index.

Remove a term from an array during a for loop

I've been creating a system for storing objects that persist for a specified duration, then remove themselves. However, I'm having some trouble figuring out how to remove expired items from the array while the for loop is running (to minimize extra iterations through the array)
Here is what I've made so far. Terms in the list are flagged with a Boolean value indicating that they're done.
For i = 0 To VisualEffects.Count - 1 Step 1
VisualEffects(i).Update(gt)
VisualEffects(i).Draw(sb, Pos, Cam)
If VisualEffects(i).CD.isExpired() Then
VisualEffects.RemoveAt(i)
i = -1
End If
Next
Why does this produce an error? How can I remove a term from an array and continue iterating through the remainder of the loop?
Regards
Ares
The line
i = -1
sets i to -1, causing the For loop to terminate.
If you can, reverse the order of the loop so that you start with the last array element and count down. That makes the remove logic much more straightforward.
.NET arrays are fixed-size so you can't actually remove an element from an array at all. You can change the value of an element, so you can set an element to Nothing to remove the object that it referred to, but the element is still there. If you read the MSDN documentation for the Array class, you'll see that the RemoveAt method throws a NotSupportedException for this reason.
If you're actually using a collection rather than an array then you can call RemoveAt but you need to loop from the last index to the first rather than first to last. That way, removing an item will not affect the indexes of those items that you are yet to visit.

For Loop iterated twice even when size of NodeList is 1

I am facing some kind of a weird(as it appears to me) problem. I have a NodeList and need to remove an element from the NodeList while iterating through it. The NodeList has only one child element , so after removing that element that NodeList does not have any child element. Ideally the for loop should have stopped after removal of that element, but this is not happening and as the for loop runs for the second time, even when there are no child elements available, I am getting a NullPointerException.
Sample XML :
<Order OrderNo="1">
<Lines>
<Line LineNo="1"/>
</Lines>
</Order>
Sample Code :
NodeList nlLine = inDoc.getElementsByTagName("Line");
for(int cntLn = 0 ; cntLn < nlLine.getLength() ; cntLn++){
Element elLn = (Element) nlLine.item(cntLn);
if(//some condition){
elLn.getParentNode().removeChild(elLn);
cntLn--;
}
}
I am getting NullPointer exception on the linewhere i am getting the Parent Node and then removing the child. Any clue/lead/help on this?
You are decrementing the loop variable cntLn--.
I am pretty sure you meant to increment it cntLn++. And since you are already incrementing, just omit the line cntLn--;
TIP: As a healthy coding practice, always use the prefix increment operator ++cntLn in case of loops (unless you explicitly need the postfix behavior).
I think this behavior is caused by the last line of your loop (cntLn--;).
Assume, the list has one child, so you start your processing with cntln=0 and length=1 which means: execute the loop. Then you remove the node since the condition is evaluated to true and you decrease the counter to -1. After that your for-loop increases cntln again to 0 and you start again but now the node list of the Lines-element is empty!
Simply omit the last line and try again ;)
Nevertheless, I think this is a critical processing since you cannot foresee side-effects when removing nodes while looping over the node list. Maybe it would be better to store the index of each node to be removed in this loop and remove them later in another loop.
Let's see what your program does.
Getting Line nodes (nlLine)
Setting the cycle variable to 0, since it's bigger than nlLine's size (1), we are going in the cycle.
Supposing the condition is true
Removing a node from XML (nlLine not updated!)
decrement the cycle variable
Cycle variable is still 0 (because of step 5.) and the nlLine hasn't been updated so we are going in to the cycle again (0 < 1)
Since elLn did not have a parent at this time NPE will be thrown (it has been removed from the XML)
Solution: leave cntLn--; out from your code. You have to step to the next element of the nodelist, since elLn.getParentNode().removeChild(elLn); won't remove your actual node from the nodeList.
Tip: usually it's a bad practice to modify the list during for cycling over it. Although it's a bit different situation, but still try to avoid. You should do it AFTER the main loop. (e.g. create a removeThese list to store the elements you want to delete from the list you are looping, and you can remove them once you are done with the main loop. It's safe, it's easy to understand and easy to manage.)
Simply increment and not decrement cntLn by one when removing the child - the upper bound of the for loop is static, so your only chance to manage the state of the for loop is to modify the loop variable.

Resources