Debugging

So I've written the same code in three different ways..all compiling fine...but the code does not work as desired...I know i have to debug...but nobody has ever taught me the skill...where can i learn debugging..been trying to do it on my own with code blocks but i can't seem to get anything correct...am ready to move to visual studio or any other IDE where i can get step by step lessons on how to debug..
thanks to anyone who can give a good suggestion..or why not..step by step method with a particular IDE...
Hi donvigor,

Are you aware of what the main facilities in an IDE's debugger are?

Can you show some code?

EDIT:

If you can, I can have a go at debugging it with c::b, and let you know what I find out.
Last edited on
thanks TheIdeasMan..the point is I WANT TO LEARN HOW TO DEBUG MYSELF :) do you have some guidelines to give me...I mean some step by step tutorials please...I just don't like it when people have to do things for me..it makes me feel useless and powerless..i can't figure out the right word...anyway am gonna post the code anyway...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

void elidup (std::vector<int>tempp, std::vector<int>tem);
int main (){
std::vector <int> temp ;
std::vector <int> tempf;

int test[5][5] = {{1,2,3,0,3},
                 {0,1,3,0,0},
                 {0,0,0,0,0},
                 {1,2,3,0,3},
                 {0,3,4,4,4},};

for (int k = 0; k < 5; )
for(int j = 0; j < 5; j++){
        temp.push_back(test[k][j]);
elidup (temp, tempf);
temp.clear();
k++;
    }

    int n = 0;
for (int i = 0; i < tempf.size(); i++)
{
     if (n < 3)
     {
         std::cout<<tempf[i]<<", "; n++;
     }
     else { n = 1; std::cout<<std::endl<<std::endl<<tempf[i]<<",";}
    }
}

void elidup (std::vector<int>tempp, std::vector<int>tem){
int val = 0;
std::vector<int>::iterator pt1, pt2;

for (pt1 = tempp.begin(); pt1 != tempp.end(); pt1++)
    for(pt2= tempp.begin(); pt2 != tempp.end(); pt2++){
if (*pt2 == *pt1) {val ++;}
if (val > 1)
    {tem.push_back(*pt1);}
    }


}



is far longer than this..but i cut tried to shorten it at much as possible...
Last edited on
> do you have some guidelines to give me...I mean some step by step tutorials please...
google is crashing a lot lately...

The first step is to define your problem.

Also, vwls r bt s sfl s whtspc, spclly n vrbl nms. s ls: !ndnttn
@ne555...do you mean debugging is a word which is general and not specific??? may be am not understanding something... I mean placing my code aside..i want to learn how to debug...you mean i can't have a general tutorial? surely all debugging will follow a certain pattern..or am i wrong?
There are different types of problem with code. For example the program may crash unexpectedly, or it may give incorrect output, or it may seem to give correct output, but get it wrong just some of the time. One more type is, the program works correctly, and has no apparent defects at all - but can still contain many bugs.

Depending upon what type of problem there is, the approach can differ substantially. In many cases, a debugger which allows the programmer to step through the code line by line, display the value of variables, set breakpoints and so on can be very useful. But it isn't the answer to all debugging.

Other approaches include thorough testing with both expected and unexpected inputs. Reviewing the code by reading it with a critical eye may highlight problem areas (though it often takes someone else other than the author to to this to best advantage). Then there is desk checking, this can involve stepping through the pseudocode version of the algorithm and / or the program code to verify correct behaviour.
Yes Chervil, thanks for your patience and your explanation..i will like to start with a tutorial of a debugger which allows me to go step by step thru my code so i see what the variables are doing...can a tutorial be given on that..with a particular IDE..that's what i meant when i posted ...
@donvigor

First, I think you need to identify exactly how your code is not working for you. As Chervil said, there a various ways "things don't work".

Is it the elidup function producing the wrong data? If so what data were you expecting? To debug effectively we (or whoever is doing the debugging) need to know what the input is, how it is processed, and what the expected output is. And what it is it that you are trying to do with this code snippet - what is the purpose?

With debugging itself, do you know how to set breakpoints, step through the code 1 line at a time, look at the value of each variable? These are fairly obvious on how to use in code::blocks.

OK, so I put your code into my c::b. The first thing I did was set a whole bunch of warnings. This can be done in the Settings -> Compiler menu. I have gcc as my compiler, -Wall is on by default, but I at least also set -Wextra, -pedantic, -std=c++11. There are lots of other ones to select as well

There was a warning about comparison of signed and unsigned on line 26, this can be fixed by making i of type size_t:

for ( size_t i = 0; i < tempf.size(); i++ ) {

I also did a select all, right click Format AStyle, to get some proper indenting. Also added braces to the for loops: I always use braces even when there is only 1 line in a statement, regardless of whether the next line is another control flow statement.

The confusing thing about your code is the call to the elidup function. It is inside the loops that cycle through the 2d test array (closing brace on line 23), but the function itself cycles through (size squared times) the tempp vector (which is the test array stretched out to a vector). So the loops are executing 25 * 25 * 25 times.

By the indentation, maybe you didn't mean the elidup function (and line 21) to be inside the for loops? If so, then this is a lesson to always format & indent your code properly. This should be really easy, almost automatic in the IDE.

The k++ on line 22, should be part of the for loop on line 17.

There might be other logical problems too, but it is hard to say without knowing what the purpose of the code is.

Any other queries - just ask :+D
It doesn't matter how many times it elidup() is called, it would have no side effects.
void elidup (std::vector<int>tempp, std::vector<int>tem);
@TheIdeasman..great..i will try to follow your small tutorial and see if i can do what you actually did..that is what i want to learn to do...

anyway what i want the code to do is simple..i have this square array..on every line of the square array i already know that a number repeats two times...i want to eliminate the repeating number on every line...only on that line...so that at the end i can print on the screen a new 3 x 3 array without the repeating numbers on every line..said in other words with distinct, unique numbers on every line...
but apart from your small tutorial which is a good starting point..is there no website where there is a good tutorial to teach what you just did with code blocks? i've searched but couldn't find nothing interesting @TheIdeasman? thats exactly what i want to learn...walk thru code step by step...and see where am getting it wrong with my own eyes..so as not to be asking people all the time and wasting a great deal of time
...
@don

ne555 is right (as always), the function has return type void - so it has no effect. Did you mean for one of the arguments to be a reference?

for a tutorial I googled
codeblocks debugger tutorial
and came up with lots of hits. The first one from wiki had screen shots.

Now we have your description of what you are after, we can work towards a good solution. A problem straight away - your data doesn't match with the rules you specified. The first line in the array has 4 unique numbers, the third has 1, the fourth has 4, - what are the rules for these situations?

Also, does the order of the input have to be preserved? If not, it is easy to std::sort then remove duplicates with the std::unique algorithm. Unfortunately std::unique only removes consecutive duplicates.

There is lots of info on this site at the the top left of this page in the reference section.

Are you allowed to use STL functions / algorithms?

Found this via google:

http://stackoverflow.com/questions/1453333/how-to-make-elements-of-vector-unique-remove-non-adjacent-duplicates


There are lots of answers shown for this question.

Sometimes debugging by looking at the value of each variable line by line can be tricky, because the problem is larger than that, and it might take some lateral thinking to deduce why it is wrong. In your case it seems to be the return type or lack of a reference as an argument. Another example might be copying things into the wrong container (or printing out the wrong one) - it all seems to calculate properly & copy properly, and yet it doesn't work ......

Hope all is well.
thanks TheIdeasMan for your patience...i entered wrong data here...i have a lot to learn...
One last question..what did ne555 meant by saying void elidup will have no "side effect" ??? i do not necessarily have to return something to make a small function work right?
@don

Well your function had a return type of void, and none of the arguments were pointers or references, so the function will have no effect on the value of variables in main().

Had you made the tem argument a reference, it would have changed tempf in main(). This is a key concept about functions: what goes on inside them is separate to everything else. The parameters are copies of the variables that exist when the function is called. An obvious way to communicate an "answer" is to return a value.

Btw, arguments are the variables or literal values that functions are called with, parameters are the variables a function receives.

The other way with using a reference or pointer is provided because it is better than passing a large data structure by value. In other words, instead of copying the whole large data structure, just send a pointer or reference to it instead. Prefer to use references instead of pointers, because they normally have to refer to a variable (unless they go out of scope), whereas a pointer can be made to point at anything - including garbage or null.

Here are some simple examples:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>

void AddTwo(int MyNumber);

int main() {

    int MyNumber =3;
    int Answer = 0;

    AddTwo(MyNumber);

    std::cout << "Answer is " << Answer << "\n";  // Prints Answer is 0

    return 0;
}

void AddTwo(int MyNumber) {
    int Answer = 0; // A local variable, not the same as Answer in main 
    Answer = MyNumber + 2; // no effect in main()
}


Here is the same thing again, this time returning a value:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>

int AddTwo(int MyNumber);

int main() {

    int MyNumber =3;
    int Answer = 0;

    Answer = AddTwo(MyNumber);

    std::cout << "Answer is " << Answer << "\n";  // Prints Answer is 5, this is what we want

    return 0;
}

int AddTwo(int MyNumber) {
    int Answer = 0; // A local variable, not the same as Answer in main 
    Answer = MyNumber + 2; // no effect in main()
  
    return Answer; // send the result back to main
}


This time using a reference for a big data container:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <vector>

// function decalarations in same order as called if possible
void AddNumber(std::vector<int>& BigVector, const int MyNumber);
void PrintVector(const std::vector<int>& BigVector);

int main() {

    int MyNumber = 3;  // declare 1 variable per line, use meaningful names, comment if need be

    std::vector<int> BigVector(15, 0); // 15 elements initialised to 0, imagine it is 1000 elements
    BigVector = {1,2,3,4,5,6,7,8,9,10};
    AddNumber(BigVector, MyNumber);

    PrintVector(BigVector);
    return 0;
}

// function definitions in same order as declared
// name the parameters the same as the arguments to reinforce the idea that they are the same
// BigVector is a reference, will change values in main()
void AddNumber(std::vector<int>& BigVector, const int MyNumber) { 
    // put comments here to describe what the function does plus
    // any preconditions like range of acceptable values etc.

    // range based for loop - good for processing all elements - easier than iterators
    // needs c++11 for this
    for (auto &item : BigVector) { // auto detects type, could have used int
         item += MyNumber;
    }
}

void PrintVector(const std::vector<int>& BigVector) /*const*/ { // if this was a class function it would be const

    for (auto &item : BigVector) {
        std::cout << item << "\n";
    }
}


So, some important things at this stage: Naming of variables & functions; proper formatting & indenting of code; understand return values, references & local variables for functions.

Some other stuff to read:

http://www.cplusplus.com/doc/tutorial/
http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml


Most important: Google & wiki are your best friends !! :+D

EDIT:

I probably shouldn't have bothered to make item a reference here, in the :
for (auto &item : BigVector)

Because it is only an int, had it have been a more complicated type - then a ref would have been worthwhile.

However it needs to be a ref in the AddNumber function so it can change the values.
Last edited on
Thanks soo much master, master TheIdeasMan for you time and explanation :)
@don

Not a problem - always a pleasure to help out :+D

But master is way too much, I am more of a Dabbler and would place myself at the low end of intermediate - there is vast amounts for me to learn yet. Knowledge is a relative thing, perhaps I know a bit more than you, but there are others who know much more than me.

Cheers.

EDIT:

Also remember that Chervil & ne555 provided key guidance too.
Last edited on
Master TheIdeasMan..sorry i had to open the thread again...after trying to makes some changes here and there...am getting the code to behave like how i want it to behave but we're still not there yet :) can you pls have a good look and at it for me? I would have loved not to disturb but i have sat behind the thing for some hours already... the conditions I gave earlier on are still holding true...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

void elidup (std::vector<int> &tempp, std::vector<int>&tem);

int main ()
{
std::vector <int> temp ;
std::vector <int> tempf;

int test[5][5] = {{1,2,3,0,3},
                 {24,1,3,0,0},
                 {1,4,5,8,8},
                 {1,2,3,0,3},
                 {0,3,35,4,4},};

for (int k = 0; k < 5; )
    {
for(int j = 0; j < 5; j++){
        temp.push_back(test[k][j]);}
elidup (temp, tempf);
temp.clear();
  k++;
    }
//for (int m = 0; m < tempf.size(); m++)
  //  std::cout<<tempf[m]<<" ";


    int n = 0;
for (int i = 0; i < tempf.size(); i++)
{
     if (n < 3)
     {
         std::cout<<tempf[i]<<", "; n++;
     }
     else { n = 1; std::cout<<std::endl<<std::endl<<tempf[i]<<",";}
    }
    return 0;
}

void elidup (std::vector<int> &tempp, std::vector<int> &tem){
int val = 0;
std::vector<int>::iterator pt1, pt2;

for (pt1 = tempp.begin(); pt1 != tempp.end(); pt1++)
    {
    for(pt2 = tempp.begin(); pt2 != tempp.end(); pt2++)
    {
if (*pt2 == *pt1) {val ++;}
    }
if (val == 1)
    {tem.push_back(*pt1);}
    }


}




one interesting thing Master... I tried to cancel out the k increment on line 25..so that i can see if the whole thing is working for only the first line single line of the multidimensional array test...and infact it seems i got locked in an infinite loop...can you please explain that...
unfortunately i still can't get code blocks debugging to work...the debugger wont open for me to see the execution of the code after looking up soo many tutorials..am sure is the setup am getting wrong...am gonna try to find a tutorial for visual studio...hope to be more lucky..thanks

Last edited on
@don

First, please quit with the "master" thing.

Please consider the advice that has been given so far, and apply it to your code. At least with naming of the variables & formatting with indents, and placement of braces. Should be easy with CodeBlocks. The only thing you have done is use references with the parameters.

It seems you are not interested in using the STL, and would rather do a C approach by analysing each item individually? And you are not willing to use or adapt any of the solutions given in the Stack Overflow link I posted?

One thing I notice, your data is now with 4 unique values per line?

If you want to test 1 line of data - then write it as such. Consider commenting out the existing code, then write one for loop that processes 5 items only. Get the simple case working first, then add complexity later. I already mentioned why line 25 is a bad idea.

Why do you have a 5 by 5 array and a 25 element vector? Your function tests all 25, but there are only 5 items in it, because of line 24. That seems confused logic to me. Can you think of a way of doing this with just two arrays & no vector?

I know you want unique listings of your numbers, what is the overall purpose of your application? What is this unique list of numbers for?

If you are having trouble with the CB debugging tutorial, then I can't help you much there - it doesn't get any clearer than that.
@ TheIdeasMan

I've considered the advice, and i realised what i forgot was the reference...now lets come to what i actually want to do...it seems i didn't make myself clear at all..
this
1
2
3
4
5
6
 
{{1,2,3,0,3},
  {24,1,3,0,0},
  {1,4,5,8,8},
  {1,2,3,0,3},
  {0,3,35,4,4},}
must become this
1
2
3
4
5
                                                    {{1,2,0,},
                                                    {24,1,3,},
                                                     {1,4,5,},
                                                      {1,2,0,},
                                                     {0,3,35,},} 

in any container type it doesn't matter...any number repeating on any line must be eliminated with itself being eliminated.
i couldn't use unique because it will delete the repeating and leave the first occurance..thats not what the code is meant to do..
what am trying to do is this...just that i haven't masterd c++ enough.. copy first line of array test in vector temp...call function elidup to eliminate a number repeating and itself...put what is left in vector tempf, clear temp...repeat for all lines of array test (THIS IS WHY I HAVE K++ in the outer loop somewhere else)...then print content of tempf out on the screen...using the rules i laid out so i get it in a 3 by 5 block...
I hope I made my self clearer now...
Mr. TheIdeasMan..i hope this explanation is enough and thorough...be patience with me, don't get angry :D sorry for earlier
Last edited on
Topic archived. No new replies allowed.