Getting rid of unused pointers in a pointers array : C++ Builder - c++

I have a Part class. And I created an array of pointers of type Part.
const int SZ = 50;
Part *myPart[SZ];
I then made a new instance of type Part inside the Part array at a random position between 0 and 50. A new instance is created every time a Button is pressed.
int x = (rand() * SZ)/RAND_MAX + 0;
myPart[x] = new Part(x);
I then put the result inside a List Box. This is executed when a second Button is pressed.
String str = "";
ListBox1->Clear();
for(int x = 0; x < SZ; x++)
{
if(myPart[x])
{
str = IntToStr(myPart[x]->getId()) + ", ";
str += myPart[x]->getStatus() + ", " + myPart[x]->getShelf() + ", ";
str += IntToStr(myPart[x]->getQuantity());
ListBox1->Items->Add(str);
}
else
{
ListBox1->Items->Add("- - - - - - - - -");
}
}
The result will appear at different places (index positions) in the List Box.
Say I pressed the randomizing button 5 times, and thus have 5 results at different random positions in the list box, how do I "push" the 5 results to the top of the stack and get rid of the 45 remaining, unused pointers?

Related

Function returns a corrupted array

I have read some old questions and tested some ideas, but my issue still exists, so here is what I want:
I need a function that returns a simple array with a fixed size of 181 integer values.
After some tests I have this function:
int *Sonar::scan(int *distances) {
// Scanning
for (int i = 0; i <= 180; i++) {
// Rotates sonar
//this->rotate(i);
// Gets the distance
//distances[i] = this->getDistance();
distances[i] = i;
}
// Returns
return distances;
}
And call it this way:
// Sonar
case 's':
int distances[181];
*distances = sonar.scan(distances);
for (int i = 0; i <= 180; i++) {
Serial.println(String(i) + ": " + String(distances[i]));
}
break;
But I get this result:
0: 1898
1: 1
2: 2
3: 3
4: 4
...
The value of index 0 is corrupted all the time. So what mistake do I make?
The first element of the array is being overwritten with the pointer to the array when you do:
*distances = sonar.scan(distances);
That is because you dereference the array with *distances giving a reference to the first element. You then assign to that with what you return from the scan method (the pointer to the array).
Just doing:
sonar.scan(distances);
would give the result you expect.
There is no need to return from the method as you are passing the array by a form of reference (a pointer) and that means the array is being changed in place.

How to use google-diff-match-patch library in C++ QT?

I've downloaded google diff library for C++ Qt.
https://code.google.com/archive/p/google-diff-match-patch/
But I don't really understand how to use it for a simple comparing of two strings.
Let assume I have two QStrings.
QString str1="Stackoverflow"
QString str2="Stackrflow"
As I understood I need to create dmp object of diff_match_match class and then call the method for comparing.
So what do I do to have for example "ove has deleted from 5 position".
Usage is explained in the API wiki and diff_match_patch.h.
The position isn’t contained in the Diff object. To obtain it, you could iterate over the list and calculate the change position:
Unchanged substrings and deletes increment the position by the length of the unchanged/deleted substring.
Insertions do not alter positions in the original string.
Deletes followed by inserts are actually replacements. In that case the insert operation happens at the same position where the delete occured, so that last delete should not increment the position.
i.e. something like this (untested):
auto diffResult = diff_main(str1, str2);
int equalLength = 0;
int deleteLength = 0;
bool lastDeleteLength = 0; // for undoing position offset for replacements
for (const auto & diff : diffResult) {
if (diff.operation == Operation.EQUAL) {
equalLength += diff.text.length();
lastDeleteLength = 0;
}
else if (diff.operation == Operation.INSERT) {
pos = equalLength + deleteLength - lastDeleteLength;
qDebug() << diff.toString() << "at position" << pos;
lastDeleteLength = 0;
}
else if (diff.operation == Operation.DELETE) {
qDebug() << diff.toString() << "at position" << equalLength + deleteLength;
deleteLength += diff.text.length();
lastDeleteLength = diff.text.length();
}
}

Displaying content with a for loop

I'm trying to write a program that randomly selects three items from an array that contains five different fruits or vegetables and then display this randomly selected content to the user. Now I'm having trouble understanding why my output is not consistent because sometimes when I run it I'll get something like this:
This bundle contains the following:
Broccoli
With the first two items missing and sometimes I'll get this:
This bundle contains the following:
Tomato
Tomato
Tomato
This is the portion of the code I'm currently having trouble with:
void BoxOfProduce::output() {
cout << "This bundle contains the following: " << endl;
// Use this so it will be truly random
srand(time(0));
for (int f = 0; f < 3; f++) {
// Here were making the random number
int boxee = rand() % 5;
// Adding the content to the box
Box[f] = Box[boxee];
// Now were calling on the function to display the content
displayWord(boxee);
} // End of for loop
} // End of output()
void BoxOfProduce::displayWord(int boxee) {
cout << Box[boxee] << endl;
}
int main() {
BoxOfProduce b1;
b1.input();
b1.output();
Can someone help me understand why i'm getting this output? Thanks!
Don't do it like you are doing it :)
Like #John3136 pointed out, you are messing up your Box variable..
void BoxOfProduce::output()
{
srand(time(NULL)); //keep in mind that this is NOT entirely random!
int boxee = rand() % 5;
int i = 0;
while(i<5)
{
boxee = rand() % 5;
cout<<Box[boxee]<<endl; //this line might be wrong, my point is to print element of your array with boxee index
i++;
}
}
Box[f] = Box[boxee]; is changing the contents of the "Box" you are picking things out of. If the first random number is 3, item 3 gets copied to item 0, so now you have twice as much chance of getting that item the next time through the loop...
You are overwriting the elements of your array with randomly selected item.
Box[f] = Box[boxee];
For eg: If boxee=1 and f=0, it will overwrite element at index 0 with 1, while at same time element at index 1 is same leaving two copies of same item.
Use :std:random_shuffle instead.

Array of characters copy error

My question is this, when the inner for loop exits, and enters back into the outer for loop it stops adding characters to the string pointer pstrDestination. Can some one explain that to me, I am not terminating the array of character so it should still write, shouldn't it?
// Does it match
if (strcmp(strCompareString, pstrToFind) == 0)
{
// Reset the index of the found letter
intFoundLetterIndex = (intFoundLetterIndex - intCompareIndex);
// Add the characters from source to destination.
for (intSourceIndex = 0; intSourceIndex < intSourceLength; intSourceIndex += 1)
{
pstrDestination[intDestinationIndex] = pstrSource[intSourceIndex];
intDestinationIndex += 1;
// Are we at the beginning of the target word
if (intSourceIndex == intFoundLetterIndex)
{
// Add the replacement characters to the destination.
for (intNewIndex = 0; intNewIndex < intReplaceWithLength; intNewIndex += 1)
{
pstrDestination[intDestinationIndex - 1] = pstrReplaceWith[intNewIndex];
intDestinationIndex += 1;
}
intSourceIndex += intToFindLength;
}
}
}
I think this
intDestinationIndex - 1;
should look like this:
intDestinationIndex -= 1;
Best I can come up with is, The Visual Studio 2013 IDE is trying to give me a huge big ol' hug.
It is terminating the string for me.
if I step the index back 1 and set the spot in the array equal to ' '. Then the loop executes as expected cause I over wrote the terminator.
after the inner loop I added;
pstrDestination[intDestinationIndex - 1] = ' ';

Another program crash on vector.push_back()

I am writing a program that reads in data from text files, sorts the data in various ways and then uses the sorted data for other calculations. Let me say that in int main(){ } there is one large for-loop that contains many other for-loops and that the segment of code that I am posting is just one of those many for-loops inside the main one.
for(t=(compare.t - 1000)*2 - 12 ;t< ( (compare.t - 1000)*2 + 12 /);t++){
rank.push_back(vector <int>() );p++;
for(ii=111;ii<2489;ii++){
if(M_screened[a][ii].size()>0){
if( fabs(M_screened[a][ii][0].t-(t*0.5 + 1000.0)) <0.257 ){
cout<<"ii = "<<ii<<" t = "<<t<<" sizeof(rank) = "<<rank.size()<<" p = "<<p;
cout<<" rank["<<p<<"].size() = "<<rank[p].size()<<endl;
cout<<" "<<endl;
cout<<"address = "<<&rank[p][rank[p].size()-1];
rank[p].push_back(ii);
cout<<" "<<endl;
}
}
}
foutT<<t*0.5 + 1000<<" "<<frequency[a][t]<<endl;} //end t-loop
All of the cout statements were just part of my own error checking process. Also, the large for-loop that contains the above code segment is able to run 2 iterations prior to crashing on the third (every single time).
Basically what I've narrowed it down to is crashing on the push_back() function. Parameter values at the time of crash:
t=177, p = 10, ii = 873, sizeof(rank) = 11, rank[10].size() = 1
Here is the error message I get from Microsoft Visual Studio :
Unhandled exception at 0x0000000077993290 (ntdll.dll) in Muon_fitting7_7_2014_statistics.exe: 0xC0000005: Access violation reading location 0x0000038085FFA1E8.
If I can provide any additional information please let me know.
I am assuming you've initialized P to zero or some such thing when declared and that is actually your problem.
for(t=(compare.t - 1000)*2 - 12 ;t< ( (compare.t - 1000)*2 + 12 /);t++)
{
rank.push_back(vector <int>() );p++;
for(ii=111;ii<2489;ii++)
{
if(M_screened[a][ii].size()>0){
if( fabs(M_screened[a][ii][0].t-(t*0.5 + 1000.0)) <0.257 ){
rank[p].push_back(ii);
}
}
}
}
At first, rank has no elements, then you push back and increment p. Now rank as 1 element but you need to use rank[p-1] to access it as p is already 1. That or initialize p to -1 to start so when you increment it, its at zero. Vector [] access is zero based.
So, try this :
int p = -1;
for(t = ((compare.t - 1000)*2 - 12);t < ((compare.t - 1000)*2 + 12);++t)
{
rank.push_back(vector <int>() );
++p;
for(ii=111;ii<2489;++ii)
{
if (M_screened[a][ii].size() > 0)
{
if (fabs(M_screened[a][ii][0].t-(t*0.5 + 1000.0)) < 0.257)
{
rank[p].push_back(ii);
}
}
}
}