Does the "delete" statement below "doubly free" an object?
(...object_list is a global vector<object*>...)
vector< object * >::iterator it, eit, iter;
object *p_object;
vector< object * > dead_objects;
it = object_list_.begin();
eit = object_list_.end();
//---collect pointers of all dead objects to dead_objects vector
for ( ; it != eit; it++ )
{
p_object = *it;
if ( p_object->is_dead() == false )
continue;
dead_objects.push_back( p_object );
}
//---free every dead object from the global object_list
for ( iter = dead_objects.begin(); iter != dead_objects.end(); iter++ )
{
p_object = *iter;
it = object_list_.begin();
eit = object_list_.end();
for ( ; it != eit; it++ )
{
if ( *it != p_object )
continue;
object_list_.erase( it );
delete p_object;
break;
}
}
I ask the question because the erase() statement above should have called the destructor of an object and freed it already, shouldn't it?
erase() does call the destructor on the object, but the destructor of a pointer type (such as object * here) does nothing -- it does NOT call delete on the pointer. If you want it to call delete, you need to use some object (such as auto_ptr<object *>) which does call delete.
It would appear not; if you have a vector of pointers to objects, calling erase() to remove one of them simply removes the pointer from the vector. You are still required to delete it yourself - this is because STL containers are designed primarily to collect objects by value.
Just a couple of suggestions - IMO your code would be clearer if you used STL algorithms like std::find instead of looping over all your vectors by hand. I'm not sure what the point of dead_objects vs object_list is - you don't seem to gain anything by storing them in the temporary vector, but something may have been lost in copying the code to SO. And std::vector is not optimal for lots of random erasures like this since erase runs in linear time - std::remove followed by erase would be a more efficient approach. For example:
for(vector<object*>::iterator it = object_list.begin(); it != object_list.end(); ++it) {
if((*it)->is_dead()) {
delete *it;
*it = NULL;
}
}
object_list.erase(std::remove(object_list.begin(), object_list.end(), NULL), object_list.end());
Related
I am writing a recursive function to find the index of a node in a linked list. It looks like this:
function indexAt(node, collection, linkedList) {
let index = 0;
if (node === nodeAt(index, linkedList,collection)) {
return index
} else {
index ++
return indexAt(node, collection, linkedList)
}
}
It calls on the nodeAt function, which looks like this:
function nodeAt(index, linkedList, collection) {
let node = collection[linkedList];
for (let i=0; i < index; i++) {
node = next(node, collection)
}
return node
}
This works fine when the index is 0, but when it is anything else, it increments the index, then sets it back to 0, entering an infinite loop. How can I fix this without fundamentally altering the code?
Well at the start of the function you reset the index to 0. So every time it recurs, it resets the index, thus causing your infinite loop.
An easy fix is to declare the index variable outside the function. That will ensure it's not reset every time the function recurs.
A better fix would be to pass the index as an argument to the function so that it will always keep track of its own index.
Just make a helper that holds the extra variable:
function indexAt(node, collection, linkedList) {
function indexAt(index, node, collection, linkedList) {
if (node === nodeAt(index, linkedList, collection)) {
return index
} else {
return indexAt(index + 1, node, collection, linkedList)
}
}
return indexAt(0, node, collection, linkedList);
}
Now you count from 0...n and make nodeAt start at the beginning each time making this O(n^2). A much better way would be that the helper has the current node, initialized at collection[linkedList] and stepping with next(currentNode) and index + 1 until node === currentNode. That would be a O(n) solution. indexAt doesn't really need to be recursive unless it is a requirement.
I've written the following code for a heap of Node*s, which are found in module node:
import std.exception, std.container;
public import node;
alias NodeArray = Array!(const (Node)*);
alias NodeHeap = BinaryHeap!(NodeArray, cmp_node_ptr);
auto make_heap() {
return new NodeHeap(NodeArray(cast(const(Node)*)[]));
}
void insert(NodeHeap* heap, in Node* u) {
enforce(heap && u);
heap.insert(u);
}
pure bool cmp_node_ptr(in Node* a, in Node* b) {
enforce(a && b);
return (a.val > b.val);
}
I then tried running the following unit tests on it, where make_leaf returns a Node* initialized with the argument given:
unittest {
auto u = make_leaf(10);
auto heap = make_heap();
insert(heap, u); //bad things happen here
assert(heap.front == u);
auto v = make_leaf(20);
insert(heap, v);
assert(heap.front == u); //assures heap property
}
The tests make it to the line I comment-marked, and then throw an enforcement error on the line enforce(a && b) in cmp_node_ptr. I'm totally lost as to why this is happening.
you are doing wrong thing in this operator:
NodeArray(cast(const(Node)*)[])
you obviously want to create empty NodeArray, but what you really got is NodeArray with one null item. NodeArray constructor takes list of values for new array as arguments, and you passing one "empty array" (which is essentially null), thus creating NodeArray with one null element.
the correct way is just:
NodeArray()
i.e.:
auto make_heap() {
return new NodeHeap();
}
make this change and everything will be fine.
p.s. it seems that D notation for multiple arguments of type U (U[] values...) made you think that constructor accepts another array as initialiser.
p.p.s. sorry, fixed make_heap() code: accidentally forgot to write "NodeArray()" in it. and edited it again, as empty NodeArray() call is not necessary there. double fault!
I have the following recursive Grails function:
private boolean isCyclic(TreeNode node) {
boolean cyclic = false
def myParents = this.parents
// if there are parents of this node
if (myParents.size() != 0) {
// if the new node is in the parents set of this node
if (myParents.contains(node)) {
cyclic = true
return cyclic
}
else {
// go into each parent of this node and test if new node is contained in their parents
myParents.each { parent ->
log.debug "go to parent: "+parent.name
if (cyclic) {
return cyclic
}
cyclic = parent.isCyclic(node)
}
}
}
return cyclic
}
How can I transform this function into a non-recursive function?
I think your code above is a contains method, rather than a cyclic check...
However here's a quick example of both a contains method and a cyclic check in an iterative style... Fingers crossed they're right
def contains( TreeNode node ) {
// if this node is the one we're looking for, return true
if( node == this ) {
return true
}
// A queue of nodes to work on
def parentQueue = this.parents as Queue
// A set of nodes we've seen (to avoid loops)
def seen = [ this ] as Set
// While we have nodes to look for
while( parentQueue ) {
// get the next node
def next = parentQueue.pop()
// Check if it's the one we're looking for
if( next == node ) return true
// And if not, add it's parents to the queue
// assuming we've not seen it before
if( !seen.contains( next ) ) {
next.parents.each { parentQueue.offer( it ) }
}
}
// Not found
return false
}
def isCyclic() {
// A queue of nodes to work on
def parentQueue = this.parents as Queue
// A set of nodes we've seen (to detect loops)
def seen = [ this ] as Set
// While we have nodes to look for
while( parentQueue ) {
// Look at the next element in the queue
def next = parentQueue.pop()
// If we've seen it before, it's cyclic
if( seen.contains( next ) ) return true
// Otherwise, record we've seen this node
seen << next
// And add its parents tothe queue
next.parents.each { parentQueue.offer( it ) }
}
// All done, not cyclic
return false
}
Tom Moertel wrote solution for this problem on his blog.
He clearly explained the transformation of recursive function into the iterative (link).
I have used his approach to transform my own functions when I needed and I was convinced that is correct.
I hope that helps.
Basically to transform a recursive function into an iterative function you should notice which is the case base(this case is the stop case of recursive function), put all functionality into a loop and use that base case as exit condition of used loop.
Perhaps i didn't explain it very well but every recursive function has an iterative function.
function BACKTRACKING-SEARCH(csp) returns a solution, or failure
return RECURSIVE- BACKTRACKING({ }, csp)
function RECURSIVE-BACKTRACKING(assignment,csp) returns a solution, or failure
if assignment is complete then
return assignment
var ←SELECT-UNASSIGNED-VARIABLE(VARIABLES[csp],assignment,csp)
for each value in ORDER-DOMAIN-VALUES(var,assignment,csp) do
if value is consistent with assignment according to CONSTRAINTS[csp] then
add {var = value} to assignment
result ← RECURSIVE-BACKTRACKING(assignment, csp)
if result ̸= failure then
return result
remove {var = value} from assignment
return failure
This is a backtracking recursion algorythm pseudocode from AIMA. However, I don't understand if it returns ALL possible solutions or just first one found. In case it is the last option, could you please help me modify it to return a list of possible solutions instead (or at least updating some global list).
EDIT: I implemented this algorithm in Java. However, there is one problem:
if I don't return assignment, but save it in result instead, the recursion stop condition fails (i.e. it doesn't exist anymore). How can I implement another stop-condition? Maybe I should return true in the end?
Here is my code :
/**
* The actual backtracking. Unfortunately, I don't have time to implement LCV or MCV,
* therefore it will be just ordinary variable-by-variable search.
* #param line
* #param onePossibleSituation
* #param result
*/
public static boolean recursiveBacktrack(Line line, ArrayList<Integer> onePossibleSituation, ArrayList<ArrayList<Integer>> result){
if (onePossibleSituation.size() == line.getNumOfVars()){
// instead of return(assignment)
ArrayList<Integer> situationCopy = new ArrayList<Integer>();
situationCopy.addAll(onePossibleSituation);
result.add(situationCopy);
onePossibleSituation.clear();
}
Block variableToAssign = null;
// iterate through all variables and choose one unassigned
for(int i = 0; i < line.getNumOfVars(); i++){
if(!line.getCspMiniTaskVariables().get(i).isAssigned()){
variableToAssign = line.getCspMiniTaskVariables().get(i);
break;
}
}
// for each domain value for given block
for (int i = line.getCspMiniTaskDomains().get(variableToAssign.getID())[0];
i <= line.getCspMiniTaskDomains().get(variableToAssign.getID())[0]; i++){
if(!areThereConflicts(line, onePossibleSituation)){
//complete the assignment
variableToAssign.setStartPositionTemporary(i);
variableToAssign.setAssigned(true);
onePossibleSituation.add(i);
//do backtracking
boolean isPossibleToPlaceIt = recursiveBacktrack(line,onePossibleSituation,result);
if(!isPossibleToPlaceIt){
return(false);
}
}
// unassign
variableToAssign.setStartPositionTemporary(-1);
variableToAssign.setAssigned(false);
onePossibleSituation.remove(i);
}
// end of backtracking
return(false);
}
This code checks if solution found and if it is, returns the solution. Otherwise, continue backtracking. That means, it returns the first solution found.
if result ̸= failure then
return result
remove {var = value} from assignment
You can modify it like that:
if result ̸= failure then
PRINT result // do not return, just save the result
remove {var = value} from assignment
Or, better, modify this part:
if assignment is complete then
print assignment
return assignment // print it and return
About edited question:
First, return true in the first if, so recursion will know that it found a solution. The second step, there is a mistake, probably:
if(!isPossibleToPlaceIt){
return(false);
}
Should be
if(isPossibleToPlaceIt){
return(true);
}
Because if your backtracking has found something, it returns true, which means you don't have to check anything else any longer.
EDIT#2: If you want to continue backtracking to find ALL solutions, just remove the whole previous if section with return:
//if(isPossibleToPlaceIt){
// return(true);
//}
So we will continue the search in any way.
I have n integers and I need a quick logic test to see that they are all different, and I don't want to compare every combination to find a match...any ideas on a nice and elegant approach?
I don't care what programming language your idea is in, I can convert!
Use a set data structure if your language supports it, you might also look at keeping a hash table of seen elements.
In python you might try
seen={}
n_already_seen=n in seen
seen[n]=n
n_already_seen will be a boolean indicating if n has already been seen.
You don't have to check every combination thanks to commutivity and transitivity; you can simply go down the list and check each entry against each entry that comes after it. For example:
bool areElementsUnique( int[] arr ) {
for( int i=0; i<arr.Length-1; i++ ) {
for( int j=i+1; j<arr.Length; j++ ) {
if( arr[i] == arr[j] ) return false;
}
}
return true;
}
Note that the inner loop doesn't start from the beginning, but from the next element (i+1).
You can use a Hash Table or a Set type of data structure that using hashing. Then you can insert all of the elements into the hashtable or hashset, and either as you insert, check if the element is already in the table/set. If for some reason you don't want to check as you go, you can just insert all the numbers and then check to see if the size of the structure is less than n. If it is less than n, there had to be repeated elements. Otherwise, they were all unique.
Here is a really compact Java solution. The time-complexity is amortized O(n) and the space complexity is also O(n).
public boolean areAllElementsUnique(int [] list)
{
Set<Integer> set = new HashSet<Integer>();
for (int number: list)
if (set.contains(number))
return false;
else
set.add(number);
return true;
}