Pointer becomes NULL immediately - c++

I have the following LLVM code. The strange thing is that the si variable of type StoreInst becomes null(0) immediately after it is allocated with new instruction outside the if block, whereas I have declared it at an outer scope. What is going on here?
Value *OldVal = NULL;
StoreInst* si = NULL;
if ( ... )
{
if ( ... )
{
....
if ( ... )
{
...
StoreInst* si = new StoreInst(...);
errs() << "si = " << si << "\n"; // Get some address here
}
errs() << "-->SI = " << si << "\n"; // Here I get NULL, why?
}
...
}
I get an output like this,
si = 0x1822ba0
-->SI = 0x0

StoreInst* si = new StoreInst(...); - You hidden the previos name si here
When the scope is ended } - you see the value of another pointer
Here is an example of what you did:
int val = 0; //first val
{
int val = 10; //other val (let's call it second)
cout << val; //second val
} // second val is destroyed here
cout << val; //first val
I've used int in the example for simplicity. Actually it can be any type

Related

C++ access an element of struct array in a struct

This thing has been driving me crazy for a while now.
I need to create and traverse (post order) a general tree where each node (a structure) is added by the user via console.
I am NOT allowed to use STL.
The user specifies how many nodes will be added, and how many 'child' nodes it can hold (number) and the name of the node (string).
Example input:
5
1 A
2 B
1 C
1 D
3 E
The above means that 5 nodes will be added. The first one (A) can accept one 'child' node, (B) can accept 2 such nodes and (C) can accept 1 etc.
The newly added nodes have to always be added to the 'highest' possible node from the top (if it still can accept a new 'child' node, if not possible you go to the next one).
The idea is to create an array (I know how many nodes will be added in total) and put those nodes specified by the user there and 'link' them accordingly using array of pointers inside of a structure.
The output of given example should be: E C D B A
I have written the whole thing as follows but I am unable to traverse the tree:
structure:
struct node {
string name = "";
int noChildrenAdded = 0;
int possibleNoChildren = 0;
int childrenFreeSlots = 0;
node* children = nullptr;
node* father = nullptr;
};
traverse function that's not working
void traverse(node* father)
{
cout << father->name << endl;
if (father == nullptr) {
return;
}
for (int i = 0; i < father->possibleNoChildren; i++) {
if (&father->children[i] == nullptr) {
continue;
}
traverse(&father->children[i]);
}
cout << father->name << "\n";
}
main
int main() {
int n = 0;
short g = 0;
string name;
cin >> n;
node* tree = new node[n];
node* tmp = nullptr;
//adding children to tree array
for (int i = 0; i < n; i++) {
cin >> g >> name;
tree[i].possibleNoChildren = tree[i].childrenFreeSlots = g;
tree[i].name = name;
tree[i].noChildrenAdded = 0;
tree[i].children = new node[1];
}
// making connections between nodes
for (int son = 1; son < n; son++) {
for (int father = 0; father < son; father++) {
if (tree[father].childrenFreeSlots > 0) {
//resizing array
if (tree[father].noChildrenAdded == 0) {
tree[father].children[0] = tree[son];
}
else {
int added = tree[father].noChildrenAdded;
tmp = new node[added + 1];
for (int i = 0; i < added; i++) {
tmp[i] = tree[father].children[i];
}
delete[] tree[father].children;
tree[father].children = nullptr;
tree[father].children = tmp;
tree[father].children[added] = tree[son];
tmp = nullptr;
}
tree[father].noChildrenAdded++;
tree[father].childrenFreeSlots -= 1;
break;
}
}
}
//this is how it should be
cout << "Father: " << tree[1].name << "\tchildren added: " << tree[1].noChildrenAdded << endl;
//tree[0].children[0] is holding pointer to drzewo[1] so the below should give me the same answer as above.
//this is giving me wrong answer
node* ptr = &tree[0].children[0];
cout << "Father: " << ptr->name << "\tchildren added: " << ptr->noChildrenAdded << endl;
//traverse(&tree[0]);
delete[] tree;
}
THE PROBLEMS
I am unable to access details of a structure (for example noChildrenAdded) - I am getting zero, despite the fact that noChildrenAdded is populated. When I access it via tree array I am getting the correct number but when I do it via pointer inside of a struct I am getting 0.
Example:
This is correct: cout << "Father: " << tree[1].name << "\tchildren added: " << tree[1].noChildrenAdded << endl;
But this is not (despite both should be giving the same number/answer):
//tree[0].children[0] is holding pointer to tree[1] so the below should give me the same answer as above.
//this is giving me wrong answer
node* ptr = &tree[0].children[0];
cout << "Father: " << ptr->name << "\tchildren added: " << ptr->noChildrenAdded << endl;
I expect I have messed up assigning children to the *children array inside of a struct. The name seems to be accessible fine but not the noChildren.
Both should be giving the same answer but they are not:
enter image description here
Any help would be greatly appreciated!
PS: when I use this code with static array of children everything is ok, traversal works fine but when I get a dynamic array it's broken. Static array alas won't do as it taking too much memory and takes way too long so my program fails the requirements.
Just as #igor-tandetnik suggested, using an array of node* pointers solved the problem. In my case solution was to use node** children not node *children.

QList request item from array not giving correct reference

Apologies if the title is incorrectly phrased - I am not too sure what is causing the problem
I am testing QList array access and came across this. It is a straight forward example of using referencing QList append() function and QList[] operator.
Aim:
I am trying to find out whether adding the same object (created with new) to 2 QList<int> and changing one of those objects (or references rather) will change the other.
What I found seems to indicate this is not true given my example and the output below:
// Some structure to simluate an object
struct IntStream {
int i;
};
// Create our lists
QList<IntStream> newlist = QList<IntStream>();
QList<IntStream> another = QList<IntStream>();
// Add 3 IntStream objects to the 2 lists using the same object, printing out the object and its reference
for (int i = 0; i < 3; i++) {
IntStream *s = new IntStream;
s->i = i;
newlist.append(*s);
another.append(*s);
qDebug() << QString("%1[%2] = %3 (").arg("newList", QString::number(i), QString::number(i)) << &another[i] << ")";
qDebug() << QString("%1[%2] = %3 (").arg("another", QString::number(i), QString::number(i)) << &another[i] << ")";
}
// Alter bject at index 1 with some arbitrary value
for (int i = 0; i < 3; i++) {
if(newlist.at(i).i == 1) {
qDebug() << "another[1] = " << &another[i];
qDebug() << "newList[1] = " << &newlist[i];
another[i].i = 4;
}
}
// Here, I should see the 2 values match, they do not
qDebug() << QString("%1 == %2 ???").arg(QString::number(newlist.at(1).i), QString::number(another.at(1).i));
The output of this is:
"newList[0] = 0 (" 0x27c75f88 )
"another[0] = 0 (" 0x27c75f88 )
"newList[1] = 1 (" 0x27c755d0 )
"another[1] = 1 (" 0x27c755d0 )
"newList[2] = 2 (" 0x27c75630 )
"another[2] = 2 (" 0x27c75630 )
another[1] = 0x27c755d0
newList[1] = 0x27c76ef0
"1 == 4 ???"
Should I expect to see 4 == 4 or did I do something wrong somewhere?
Notes:
I am using the T &QList::operator[](int i), not const T &QList::operator[](int i) const
Creating new objects rather than storing scoped objects
qDebug() << QString("%1[%2] = %3 (").arg("newList", QString::number(i), QString::number(i)) << &another[i] << ")";
qDebug() << QString("%1[%2] = %3 (").arg("another", QString::number(i), QString::number(i)) << &another[i] << ")";
You compared twice the &another[i]. You should write &newlist[i] instead in the first line.
And when you call newlist.append(*s); you made a copy of your IntStream instance.
To answer to your need :
"I am trying to find out whether adding the same object (created with new) to 2 QList and changing one of those objects (or references rather) will change the other."
Use a shared_ptr to shared your instance between multiple list.
Something like :
struct IntStream {
int i;
};
// Create our lists
QList<std::shared_ptr<IntStream >> newlist = QList<std::shared_ptr<IntStream >>();
QList<std::shared_ptr<IntStream >> another = QList<std::shared_ptr<IntStream >>();
// Add 3 IntStream objects to the 2 lists using the same object, printing out the object and its reference
for (int i = 0; i < 3; i++) {
std::shared_ptr<IntStream > s = std::make_shared<IntStream >();
s->i = i;
newlist.append(s);
another.append(s);

How can I traverse a Huffman Tree (via code) and print out the encodings for each letter?

I'd like to start with what I know about heaps and Huffman code.
For this project, we use a minimum heap. The top part of the upside-down tree (or root) holds the minimum element. Whenever something is added to the array, everything gets moved, so the root is always the minimum value element. Whenever an element is deleted, everything gets reconfigured with the top element holding the minimum once again. In class, we went over a (template) class called MaxHeap, which I converted into MinHeap without the template stuff.
My professor went over Huffman encoding, but I understood it best using this visual tool:
https://people.ok.ubc.ca/ylucet/DS/Huffman.html
The idea is to use a minimum heap as follows:
1. Delete two nodes
2. Create a new node with the deleted nodes as children. The frequency of this node is the summation of the two children frequencies.
3. Add this new node to the minimum heap
This process repeats until there is one node left in the heap (the root). Next, we find the encodings for each letter. To do this, travel down the tree with left movement being 0 and right movement being 1. Traveling right twice then left once would give 110 for the letter 'c' in my tree (image link can be found towards the bottom of my post).
Everything was going mostly fine until I needed to traverse from the root. I had no idea how to do this via code, so I tried googling the answers and found these two websites:
https://www.geeksforgeeks.org/huffman-coding-greedy-algo-3/
https://www.programiz.com/dsa/huffman-coding
I copied their function printCodes() into my code, but I didn't get see it work.
When I try manually going down the tree, I get two things. For example, I tried traveling left down the root and using cout to see the values. I expected to see 40, !, e, d; but when I tried I was getting gibberish number and characters (greek letters like theta, sigma, etc). It gets really weird because on line 207, yourRoot->left->freq gives me 40, but the same thing on the line 208 of code gives me a large number. When I traveled right, I got: Exception thrown: read access violation. yourRoot->right->right->letter was 0xCCCCCCCC.
To reiterate cout << yourRoot->left->freq << endl; will give me 40 the first time I call it, but the second time I get a random number. I expected the same output twice in a row. Am I supposed to keep a pointer or pointer-to-pointer to the address of yourRoot or something?
Another problem is in createHuffmanTree(), if I put return root; outside the while loop I get this error and the code doesn't run at all:
potentially uninitialized local pointer variable 'root' used
Both of these things were odd problems and I assume it has to do with the way I'm using & and * symbols. I tried using something like this:
MinHeap yourHeap = MinHeap(6);
node *item = newNode(30, 'f');
yourHeap.Insert(*item);
item = newNode(20, 'e');
yourHeap.Insert(*item);
item = newNode(20, 'd');
yourHeap.Insert(*item);
item = newNode(15, 'c');
yourHeap.Insert(*item);
item = newNode(10, 'b');
yourHeap.Insert(*item);
item = newNode(5, 'a');
yourHeap.Insert(*item);
delete item;
This works the same as the yourList[] code I have in main(), but I figured "keep it simple stupid" and avoid using pointers since I clearly have some issues with them.
I uploaded an output without any error causing code and a drawing of what I expect my tree to look like with the values I want to use (https://imgur.com/a/Vpx7Eif). If the link doesn't work, please let me know so I can fix it.
The code I have thus far is:
#include <iostream>
using namespace std;
#define MAX_TREE_HEIGHT 20
//exception is thrown if wrong input
class NoMem
{
public:
NoMem() { cout << "Heap is full\n"; }
};
class OutOfBounds
{
public:
OutOfBounds() { cout << "Heap is empty\n"; }
};
struct node
{
int freq;
char letter;
struct node *left, *right;
};
// initialize node with frequency and letter
node* newNode(int freq, char letter)
{
node *temp = new node;
temp->freq = freq;
temp->letter = letter;
temp->left = nullptr;
temp->right = nullptr;
return temp;
}
// initialize node using two nodes as children
node* newNode(node& a, node& b)
{
node *temp = new node;
temp->freq = a.freq + b.freq;
temp->letter = '!';
temp->left = &a;
temp->right = &b;
return temp;
}
class MinHeap {
public:
MinHeap(int MSize)
{
MaxSize = MSize;
heap = new node[MaxSize + 1];
Size = 0;
}
~MinHeap() { delete[] heap; }
MinHeap& Insert(node& x);
MinHeap& Delete(node& x);
void Display();
int Size;
private:
int MaxSize;
node *heap;
};
MinHeap& MinHeap::Insert(node& x)
{
if (Size == MaxSize) throw NoMem();
else
{
printf("Inserting '%c' with frequency of %d. ", x.letter, x.freq);
int i = ++Size;
while (i != 1 && x.freq < heap[i / 2].freq)
{
heap[i] = heap[i / 2];
i /= 2;
}
heap[i] = x;
Display();
return *this;
}
}
MinHeap& MinHeap::Delete(node& x)
{
if (Size == 0) throw OutOfBounds();
x.freq = heap[1].freq; // root has the smallest key
x.letter = heap[1].letter;
printf("Deleting '%c' with frequency of %d. ", x.letter, x.freq);
node y = heap[Size--]; // last element
int vacant = 1;
int child = 2; //make child = left child
while (child <= Size)
{
if (child < Size && heap[child].freq > heap[child + 1].freq) ++child;
// right child < left child
if (y.freq <= heap[child].freq) break;
heap[vacant] = heap[child]; // move smaller child
vacant = child; // new vacant
child = child * 2; // new child of vacant
}
heap[vacant] = y;
Display();
return *this;
}
void MinHeap::Display()
{
printf("Your heap contains: ");
for (int i = 1; i <= Size; i++)
printf("'%c' = %d, ", heap[i].letter, heap[i].freq);
printf("\n");
}
node* createHuffmanTree(MinHeap& yourHeap)
{
cout << "--- Creating Huffman Tree ---\n";
node left, right, *root;
while (yourHeap.Size > 1)
{
yourHeap.Delete(left);
yourHeap.Delete(right);
root = newNode(left, right);
cout << "-> New Node: freq = " << root->freq << ", letter = " << root->letter << ", left: " << root->left->letter << ", right: " << root->right->letter << endl;
yourHeap.Insert(*root);
if (yourHeap.Size < 2)
{
return root;
}
}
//return root; // potentially uninitialized local pointer variable 'root' used
}
void outputHuffmanCode(node* root, int arr[], int top)
{
// left movement is 0
if (root->left)
{
arr[top] = 0;
outputHuffmanCode(root->left, arr, top + 1);
}
// right movement is 1
if (root->right)
{
arr[top] = 1;
outputHuffmanCode(root->right, arr, top + 1);
}
// if reached leaf node, must print character as well
if (!(root->left) && !(root->right))
{
cout << "'" << root->letter << "' = ";
for (int i = 0; i < top; ++i)
cout << arr[i];
cout << endl;
}
}
int main()
{
node yourList[6];
yourList[0].freq = 5;
yourList[0].letter = 'a';
yourList[1].freq = 10;
yourList[1].letter = 'b';
yourList[2].freq = 15;
yourList[2].letter = 'c';
yourList[3].freq = 20;
yourList[3].letter = 'd';
yourList[4].freq = 20;
yourList[4].letter = 'e';
yourList[5].freq = 30;
yourList[5].letter = 'f';
cout << "Here is your list: ";
for (int i = 0; i < 6; i++)
{
cout << "'" << yourList[i].letter << "' = " << yourList[i].freq;
if (i < 5) cout << ", ";
} cout << endl;
MinHeap yourHeap(6);
yourHeap.Insert(yourList[5]);
yourHeap.Insert(yourList[4]);
yourHeap.Insert(yourList[3]);
yourHeap.Insert(yourList[2]);
yourHeap.Insert(yourList[1]);
yourHeap.Insert(yourList[0]);
/*
MinHeap yourHeap = MinHeap(6);
node *item = newNode(30, 'f');
yourHeap.Insert(*item);
item = newNode(20, 'e');
yourHeap.Insert(*item);
item = newNode(20, 'd');
yourHeap.Insert(*item);
item = newNode(15, 'c');
yourHeap.Insert(*item);
item = newNode(10, 'b');
yourHeap.Insert(*item);
item = newNode(5, 'a');
yourHeap.Insert(*item);
delete item;
*/
node *yourRoot = newNode(0, NULL);
yourRoot = createHuffmanTree(yourHeap);
// same cout twice in a row, different results
//cout << yourRoot->left->freq << endl;
//cout << yourRoot->left->freq << endl;
cout << "L0 Root: freq = " << yourRoot->freq << ", letter = " << yourRoot->letter << ", left freq: " << yourRoot->left->freq << ", right freq: " << yourRoot->right->freq << endl;
cout << "L11 Left: freq = " << yourRoot->left->freq << ", letter = " << yourRoot->left->letter << ", left: " << yourRoot->left->left->letter << ", right: " << yourRoot->left->right->letter << endl;
//cout << "R11 Left: freq = " << yourRoot->right->freq << ", letter = " << yourRoot->right->letter << ", left: \n";
//<< yourRoot->right->left->letter << ", right: " << yourRoot->right->right->letter << endl;
//int arr[MAX_TREE_HEIGHT], top = 0;
//outputHuffmanCode(yourRoot, arr, top);
system("pause");
return 0;
}
I'd like to thank whoever reads and replies to this post in advance. I think I've given as much information as I could. If I did anything that's against community rules, please let me know so I can fix my mistake(s).
In your createHuffmanTree Function, you create the node's left and right...
with root = newNode(left, right); you let the left/right member of your struct point to the address of the (temporary) node you've created in createHuffmanTree (that means in
node* newNode(node& a, node& b)
the address of a and b is always the same..
and the node goes out of scope after leaving the createHuffmanTree function - i think this causes your problem. You know what I mean?

Assigning a struct pointer value from struct vector

#include <iostream>
#include <vector>
using namespace std;
struct Sn {
int SnId;
double spentEnergy;
};
class Node {
//other stuff
private:
vector<Sn> SnRecord;
public:
int getBestSn(Sn* bestSn);
void someFunction();
};
int main()
{
Node nd;
nd.someFunction();
return 0;
}
void Node::someFunction() {
//adding some records in vector just for testing purpose
Sn temp;
temp.SnId = 1; temp.spentEnergy = 5;
SnRecord.push_back(temp);
temp.SnId = 2; temp.spentEnergy = 10;
SnRecord.push_back(temp);
temp.SnId = 2; temp.spentEnergy = 10;
SnRecord.push_back(temp);
cout << "Size of SnReocord is " << SnRecord.size() << endl;
//choosing best sn
Sn *bestSn;
int returnCode = -1;
returnCode = getBestSn(bestSn);
if (returnCode == 0){ //means there is a best SN
cout<< "Found best SN with id = "<< bestSn->SnId << endl;
}
else {
cout <<"NO SN "<< endl;
}
}
int Node::getBestSn(Sn* bestSn) {
int tblSize = (int)SnRecord.size();
if (tblSize == 0)
return -1;
//here i have to assign *bestSn a selected value from vector
//suppose SnRecord[2] is best Sn
cout << "Best sn id is " << SnRecord[2].SnId<< endl; //works OK,
bestSn = &SnRecord[2]; ///// giving me core dump ERROR in my own program but in this simplified version it only gives wrong value
return 0;
}
The output now is:
Size of SnReocord is 3
Best sn id is 2
Found best SN with id = 520004336
In my own program it gives me Core dump error, if I comment this line (and make proper other comments according to function call), the error is gone and simulation executes normally.
I saw examples with arrays, the work if a pointer is assigned a value in this way:
int numbers[5];
int * p;
p = &numbers[2]; //works OK.
but for vectors its not working. Or may be its problem of vector of structures, I'm unable to figure out. Any suggestions?
Ok actually the problem is solved by using suggestion of Sn* & bestSn. But I don't understand this solution. Why can't I pass a pointer variable and it saves a pointer value in it which latter could be accessed?

c++ process does not stop

There is something wrong in the code but I do not understand why.
I think one of the reason could be the threads that I used in the code.
The code looks like this.
in main.cpp
vector<thread> t;
vector<future<myClass>> futures;
vector<myClass> chV;
for(int i = 0; i < NumberOfThreads; i++) // NumberOfThreads are 2 here
{
promise<myClass> promises;
futures.push_back(promises.get_future());
t.push_back(thread(MyFunction ,i, PointsNumberInThreads , pointList, std::move(promises)));
}
for_each(t.begin(), t.end(), std::mem_fn(&std::thread::join));
for(int i = 0; i < futures.size(); i++ )
{
// futures.at(i).get().fOut(i); // <-- if I comment out then it gives error. but why?
chV.push_back(futures.at(i).get());
}
myClass c1 = chV.at(0);
myClass c2 = chV.at(1);
cout << "merge start" << endl; // <-- it prints out
c1.Merge(c2);
cout << "merge end" << endl; // <-- does not print out this message. so I have to kill the process
the Merge function in the myClass.cpp I have these sentences at the bottom of the function.
int aSt,aMid,aEnd;
int bSt,bMid,bEnd;
aSt = 0, aEnd = upperV.size(), aMid = (aEnd + aSt)/2;
bSt = 0, bEnd = b.upperV.size(), bMid = (bEnd + bSt)/2;
Point aPoint, bPoint, aPrev, aNext, bPrev, bNext;
aPoint = upperV.at(aMid);
aPrev = upperV.at(aMid-1);
aNext = upperV.at(aMid+1);
bPoint = b.upperV.at(bMid);
bPrev = b.upperV.at(bMid-1);
bNext = b.upperV.at(bMid+1);
bool done = true;
while(done)
{
done = false;
if(orientation(aPoint,bPoint,bPrev) > 0)
{
bEnd = bMid;
bMid = (bEnd + bSt)/2;
bPoint = b.upperV.at(bMid);
done = true;
}
if(orientation(aPoint,bPoint,bNext) > 0)
{
bSt = bMid;
bMid = (bEnd + bSt)/2;
bPoint = b.upperV.at(bMid);
done = true;
}
if(orientation(bPoint,aPoint,aPrev) < 0)
{
aEnd = aMid;
aMid = (aEnd + aSt)/2;
aPoint = upperV.at(aMid);
done = true;
}
if(orientation(bPoint,aPoint,aNext) < 0)
{
aSt = aMid;
aMid = (aEnd + aSt)/2;
aPoint = upperV.at(aMid);
done = true;
}
}
cout << "aPoint = (" << aPoint.x << " , " << aPoint.y << ")" << endl;
cout << "bPoint = (" << bPoint.x << " , " << bPoint.y << ")" << endl;
and they are printed but as I mentioned the process seems to keep running in somewhere.
This is the section of code that I think you should be concerned with. This may
not be why your code is continuing execution as you have stated in your problem, but from the code that you did provide to us; I still think this is an issue that should be addressed.
bool done = true;
while(done)
{
done = false;
if(orientation(aPoint,bPoint,bPrev) > 0)
{
bEnd = bMid;
bMid = (bEnd + bSt)/2;
bPoint = b.upperV.at(bMid);
done = true;
}
if(orientation(aPoint,bPoint,bNext) > 0)
{
bSt = bMid;
bMid = (bEnd + bSt)/2;
bPoint = b.upperV.at(bMid);
done = true;
}
if(orientation(bPoint,aPoint,aPrev) < 0)
{
aEnd = aMid;
aMid = (aEnd + aSt)/2;
aPoint = upperV.at(aMid);
done = true;
}
if(orientation(bPoint,aPoint,aNext) < 0)
{
aSt = aMid;
aMid = (aEnd + aSt)/2;
aPoint = upperV.at(aMid);
done = true;
}
}
You are initially setting this to be true. You are then going into your while loop and are setting it to false. All of your if statements set it back to true. So if any of these conditions are met depending on what orientation() returns then you are not going to break out of this while loop. It may seem to be illogical at first, but I learned over time that a good way to do while loops is in this structure.
bool done = false;
while ( !done ) {
// terminating case - I usually almost always check for this first!
if ( done ) {
break;
}
// Do work here and one or more cases could trip done to be equal to true
// within a if... else if ... else statement or within a series of if satements
// or none of them can, but if they don't then it must be set at the end of the while loop.
// Any one of these or all of them could set done = true and if they don't
// then you should set done = true at the end of the while loop since
// if none of these conditions are met, it will execute the assignment
// before it begins to loop.
if ( some condidition ) {
// Do this
} else if ( some other condidition ) {
// Do this instead
} else {
// Then do this
}
// Or this: Any of these could trip done = true or none of them
// and once again if none of them do, it should be the last thing done
// before the ending brace to your while loop.
if ( this ) {
// Do Work;
}
if ( this ) {
// Do Work;
}
// etc.
// Set this last if none of the if statements trip done to be true;
// otherwise if one or more does trip done, then you can omit this line.
// Note: If none of the if statements trip this flag and you trip it here
// in this section, this loop will occur only one time.
done = true;
}