I'm using lldb to debug a C++ program which has the following code
// Brute force to inner points
for (int i = 0; i < y_strip.size(); i++) {
for (int j = i + 1; j < y_strip.size(); j++) {
// If the vertical distance between the points is greater
// than delta, break the loop
if (abs(y_strip[i].y - y_strip[j].y) > delta) {
break;
} else {
mid_min_distance = minimal_distance(y_strip[i], y_strip[j]);
mid_min = min(mid_min_distance, mid_min);
}
}
}
and I want to come up with a way of stopping the program if the difference between j and i is greater than 10. How can I do this?
Compiling the program with clang++ -Wall -g closest.cpp -o closest
(lldb) break set -p "If the vertical distance between" -c "abs(i - j) > 10"
will do the trick. The -c option here is the breakpoint condition; if that expression evaluates to true, the program will stop at the breakpoint, otherwise the program will keep running. Note that you are still stopping to check the condition every time round the two loops, and this condition runs a function, so if the code you are checking is going to get run a lot, evaluating the condition might get slow. In that case it might be worth rewriting the condition to something like:
i - j > 10 || j - i > 10
since a simple expression with no function calls can be emulated in the debugger w/o having to call code in the debugee to check the condition.
And if this is code that you can modify, and it is going to get called a whole lot so that stopping each time around the loop to check the condition would be a big performance hit, then you can just put the check in your code:
if (abs(i - j) > 10)
printf ("Set a breakpoint here.\n");
rebuild it, and then just do:
(lldb) break set -p "Set a breakpoint here"
Note, the -p breakpoint option sets a breakpoint on the line whose source matches the pattern given in the option argument. You can also use file & line breakpoints:
(lldb) break set -f closest.cpp -l <whatever>
I like the pattern one because it moves with the intended location as the code is edited and it means I don't have to count lines.
Related
From this site https://www.geeksforgeeks.org/lca-for-general-or-n-ary-trees-sparse-matrix-dp-approach-onlogn-ologn/
I have a problem with this while loop part:
// runs till path 1 & path 2 mathches
int i = 0;
while (path[1][i] == path[2][i])
i++;
I want to increment i until two array elements are equal and I expected this loop to be like:
// runs till path 1 & path 2 mathches
int i = 0;
while (path[1][i] != path[2][i])
i++;
because I want to increment "i" when values are not equal but it does not seem so. Why equality is checked instead of inequality? This while loop confuses my mind. (Note: I run the whole code and it is working.)
By the line which follows (in your reference) where the last matching is returned, I see it that the error is in the comment. It should say something like "runs as long as the paths match" not "till".
Suppose I want to solve the equation x + 3 = 40 using GNU bc. One way I could do this would be to start by checking to see if 0 is a solution, then checking 1, and so on, until I get to the right answer. (Obviously not the best way to do algebra, but oh well.) So I enter the following code into GNU bc:
int solver(int x);
define solver(x){
if(x + 3 == 40) return x;
x = x + 1;
solver(x)
}
solver(0)
It produces 37 - the right answer, of course - but the 37 is then followed by 37 zeros. Based on some experimentation, it seems like each zero comes from an instance of the if statement being false, but how do I prevent the zeros from showing up? I'm using GNU bc to solve more complicated functions and create more complex lists of numbers, so it really isn't practical for me to sort through all the zeros. Any help would be appreciated, since I haven't yet figured anything out.
For each operation that isn't an assignment, bc prints an exit status. One way to suppress that is to assign to the dummy value . (which is just the value of the last result anyway), another way is to make sure you explicitly print exactly what you need.
I would have written your function like this:
#!/usr/bin/bc -q
define solver(x) {
if (x + 3 == 40) return x
return solver(x+1)
}
print solver(0), "\n"
quit
A few remarks for your attempt:
I don't understand what your first line is supposed to do, I just dropped it
I've indented the code, added some whitespace and removed the semicolons – mostly a matter of taste and readability
I've simplified the recursive call to avoid the solver(x) line stand on its own, as this produces the spurious 0
As for your suspicion that the if statement produces the zeroes: try, in an interactive session, the following:
1 == 2 # Equality test on its own produces output
0
1 == 1 # ... for both true and false statements
1
if (1 == 2) print "yes\n" # No output from false if condition
if (1 == 1) print "yes\n" # If statement is true, print string
yes
Having just switched to lldb, I'm trying to do the equivalent of gdb's watch i being I'm inside a for loop in my code.
(lldb) f
frame #0: 0x0000000100000664 a.out`MaxPairwiseProduct(numbers=size=5) + 4 at max_pairwise_product.cpp:19 [opt]
16 // Find max value in vector
17
18 for (int i=1; i<numbers.size(); i++) {
-> 19 if (numbers[i] > numbers[i-1]) {
20 second_max = max;
21 max = numbers[i];
22 if (numbers[i] < max && numbers[i] > second_max)
(lldb)
As you can see above, int i has already been declared.
Checking which watchpoints I have yields
(lldb) watchpoint list -b
Number of supported hardware watchpoints: 4
No watchpoints currently set.
(lldb)
Now trying to set a watchpoint to i (according to the lldb reference) I get
(lldb) wa s v i
error: Watchpoint creation failed (addr=0xffffffffffffffff, size=0, variable expression='i').
error: cannot set a watchpoint with watch_size of 0
(lldb)
I don't understand why this is, being the variable has been declared. Googling the error didn't help much as most issues seem to be related with hitting the max number of watchpoints, which is not my case as can be seen above. Any help would be much appreciated!
I changed the way I was compiling the program to clang++ -Wall -g -o max_pairwise max_pairwise.cpp and it started showing me the right information, including tracking the value of i
I have this piece of code in my school book.
#include<iostream>
using namespace std;
int main() {
int x=10,c=1;
while (c < 5) {
x += x*c;
c *= 2;
c++;
c -= 2;
cout << "X=" << x<<'\n';
}
system("pause");
return 0;
}
As you can see it's an infinite loop, when logically traced, it should show 20,40,80 and so on.
However it always shows 0.
when adding system("pause") after each loop cycle it shows the correct values, but when left as shown above (infinitely looping) it shows zero.
Any ideas of the reason?
c is always 1 no matter what. The loop becomes infinite. Eventually, X becomes 0 due to integer overflow.
c = 1
c *= 2; c = 2
c++; c = 3
c -= 2; c = 1 <-- infinite
Here is my answer for your questions:
Why do you get infinitely looping?
awesomeyi did answer you above, because the condition of the while loop is always true, so it is never ended.
Why does X always equal to 0?
Please pay your attention on X varable, its value will be increased after ending one loop x += x*c. Because you are in the infinitely loop, x's value will be increased forever until greater than the limited value of an integer variable. Then, the value will be set as zero. Please see my output when running your code.
Removing the pause doesn't cause it to always show zero. It just prints output so quickly that zeroes are all you see at the bottom. Add the pause back in and click through about 30-40 iterations and see if it helps you understand what is happening.
Update:
So it turns out there were two issues:
The first is that I checked the [k-1] index before I checked k == 0. This was a crash, although mostly fixable, and not the primary issue I posted about.
The primary issue is that the code seems to execute only after I press ctrl+z. Not sure why that would be.
Original:
So, learning from Stroustrup's text in C++ programming, I got to an example on vectors and tried implementing it myself. The gist is that the program user enters a bunch of words, and the program alphabetizes them, and then prints them without repeats. I managed to get working code using a for statement, but one of my initial attempts confuses me as to why this one doesn't work.
To be clear, I'm not asking to improve this code. I already have better, working code. I'm wondering here why the code below doesn't work.
The "error" I get is that the code compiles and runs fine, but when I input words, nothing happens and I'm prompted to input more.
I'm certain there's an obvious mistake, but I've been looking everywhere for the last 8 hours (no exaggeration) just devoted to finding the error on my own. But I can't.
int main() {
vector<string> warray; string wentry; int k = 0;
cout << "Enter words and I'll alphabetize and delete repeats:\n\n";
while (cin >> wentry) warray.push_back(wentry);
sort(warray.begin(), warray.end());
while (k < warray.size()) {
if (warray[k - 1] != warray[k] || k == 0) cout << warray[k] << "\n";
++k;
}
}
My reasoning for why this should work is this: I initialize my array of words, my word entry per input, and a variable to index word output.
Then I have a while statement so that every input is stacked at the end of the array.
Then I sort my array.
Then I use my index which starts at 0 to output the 0th item of the array.
Then so long as there are words in the array not yet reached by the index, the index will check that the word is not a repeat of the prior index position, and then print if not.
No matter what whappens, the index is incremented by one, and the check begins again.
Words are printed until the index runs through and checks all the words in the array.
Then we wait for new entries, although this gets kind of screwy with the above code, since the sorting is done before the checking. This is explicitly not my concern, however. I only intend for this to work once.
To end the cycle of input you need to insert EOF character which is ctrl+d. However, there are other problems in your code. You have k = 0 to start with so the moment you will try warray[k - 1] your code will crash.
At the point where you take
warray[k - 1]
for the first time, k is zero, so you want to get the warray value at index -1, which is not necessarily defined in memory (and even if, I wouldn't do this anyway). So as it compiles, I guess the address is defined in your case by accident.
I would try simply reversing the OR combination in your if-condition:
if (k == 0 || warray[k - 1] != warray[k])
thus for the first iteration (k == 0) it won't check the second condition because the first condition is then already fulfilled.
Does it work then?
You're stuck in the while loop because you don't have a way of breaking out of it. That being said, you can use Ctrl + d (or use Ctrl + z if executing on windows in the command prompt) to break out of the loop and continue executing the code.
As for while loop at the bottom which prints out the sorted vector of values, your program is going to crash as user902384 suggested because your program will first check for warray[k - 1].
Ideally, you want to change the last part of your program to:
while (k < warray.size())
{
if (k == 0 || warray[k - 1] != warray[k])
cout << warray[k] << "\n";
++k;
}
This way, the k == 0 check passes and your program will skip checking warray[k - 1] != warray[k] (which would equal warray[-1] != warray[0] when k=0).
You just needed to reverse:
if (warray[k - 1] != warray[k] || k == 0)
to
if (k == 0 || warray[k - 1] != warray[k] )
for terminating this condition if k = 0.
An alternative.
Although it can termed as a bit off topic, considering you want to work with std::vector<>, but std::set<> is an excellent container which satisfies your current two conditions:
Sort the strings in alphabetical order.
Delete all the repetitions.
Include <set> in your .cpp file, and create a set object, insert all the std::string and iterate through the set to get your ordered, duplicate-free strings!
The code:
int main() {
//Define a set container.
set<string> s;
//A temporary string variable.
string temp;
//Inserting strings into the set.
while (cin >> temp) s.insert(temp);
//Create a set<int> iterator.
set<string>::iterator it;
//Scanning the set
for(it = s.begin(); it != s.end(); ++it)
{
//To access the element pointed by the iterator,
//use *it.
cout<<*it<<endl;
}
return 0;
}
I just recommended this container, because you will study set in Stroustrup's text, and it is very easy and convenient instead of laboring over a vector.