Thread: Codeblocks.

  1. #1
    Registered User
    Join Date
    May 2010
    Posts
    62

    Codeblocks.

    I was told to compile the following to see what errors the compiler gives when you try to compile a program that goes past the upper bound of an array. However codeblocks did not give me any errors. Now my question is if it is possible for codeblocks to do this by changing something in it's setting?
    Code:
    #include <iostream>
    using namespace std;
    
    int main()
    {
     long TargetArray[25];   // Array to fill
    
     int i;
      for (i = 0; i < 25; i++)
       TargetArray[i] = 10;
    
     cout << "Test 1: \n";   // test current values, should be 0
     cout << "TargetArray[0]: " << TargetArray[0] << endl;   //lower bound
     cout << "TargetArray[24]: " << TargetArray[24] << endl << endl;   // upper bound
    
     cout << "\nAttempting at assigning values beyond the upper bound...";
     for (i = 0; i <= 25; i++)   // going a little to far
     TargetArray[i] = 20; // asigning my fail for element 25
    
     cout << "Test 2: \n";
     cout << "TargetArray[0]: " << TargetArray[0] << endl;
     cout << "TargetArray[24]: " << TargetArray[24] << endl;
     cout << "TargetArray[25]: " << TargetArray[25] << endl;   //out of bounds
    
     return 0;
    }

  2. #2
    Making mistakes
    Join Date
    Dec 2008
    Posts
    476
    Bound-checking is not present in C++, so actually no (unless you use specific compilers). Maybe it will crash, but the compiler will happily compile it. If you want such a thing, use std::vectors.

  3. #3
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    std::vectors don't have COMPILE TIME bound checking either.

    I don't know any language that does.

  4. #4
    Registered User
    Join Date
    Aug 2005
    Posts
    266
    kitten im sure your professor might of meant during run-time, if he didn't then I guess you can say nothing happened

  5. #5
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    If you are on Linux, an open source tool that seems to work well (I just tried it on this problem for the first time) is called cppcheck. If you are on a Debian or Ubuntu type install, just do a <sudo if needed> apt-get install cppcheck. I created a demo project with no fancy switches to gcc (same thing CodeBlocks use I think) and inserted your test code into it, then ran cppcheck against the buggy file. Here is the output:
    Code:
    jeff@jeff-gate:~/dev/bounds$ cppcheck -a ./boundscheck_main.cpp
    Checking ./boundscheck_main.cpp...
    [./boundscheck_main.cpp:29]: (all) Buffer overrun
    [./boundscheck_main.cpp:34]: (all) Array index out of bounds
    jeff@jeff-gate:~/dev/bounds$
    .

    The two lines in my source that it was pointing to are:
    Code:
          TargetArray[i] = 20; // asigning my fail for element 25 (line 29)
    and
      cout << "TargetArray[25]: " << TargetArray[25] << endl;   //out of bounds (line 34)
    I know this may not be what you wanted but I do find it funny that my usual "go-to" tool for this sort of thing, valgrind, just kind of stops just before the first test so I thought to try this...

    Here is a link for the project. Being a console tool, it may compile under Winders and almost certainly will under Mac:
    SourceForge.net: cppcheck

    Update: looking at the source forge article for it, I see there is a plugin for CodeBlocks. Heh.
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

  6. #6
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    An interesting (to me, who has no life I guess) update on this problem:

    First, the cppcheck tool I used above is a static source code checker which means it analyzes the source code as-is; you don't have to compile anything into the app, you don't have to run it, etc. This I think is more on the lines of what the OP was looking for WRT CodeBlocks.

    However one of my favorite tools for finding non-obvious memory and resource issues is Valgrind. Valgrind falls into the category of tools that examine a running app and watch for memory leaks, overruns, etc that way. Normally this approach is some powerful mojo but in this particular case it fell on its face. When run as written above (well in my source I just made the test a separate function and called it from main()), when the app gets to the first actual bug (for loop that iterates beyond the end of the array) the program just stops, requiring a Ctrl-C to break it. GDB acted the same way and electric fence acted the same way as well. The print statement just before it never resulted in something going to the screen. This is and of itself is a bug too when viewed in the context of debugging this app because there is no endl at the end so the buffers are not flushed and since the next line stops the program, the line of text never appears (endl, in addition to supplying a carriage return/line feed also flushes your buffers). Now here is the interesting part: to problem of the end-of-array overwrite means that the address of array[24+1] is somewhere in the code so by overwriting that, you are likely stepping on other code preventing the app from finishing. As a sort of test, I added the following just after that for loop:
    Code:
       int dodgyIndex =-1;
       TargetArray[dodgyIndex] = 20;
    Slightly altering the memory footprint of the app and even with the bad for() loop it ran to completion, probably because I gave it a non-essential bit of code to step on. The same or similar results could have been achieved by allocating TargetArray on the heap via new or making it static. This points to a subtle yet nice bullet to have in your debugging armament: if you suspect a memory block is being violated in any way, change where it is being allocated. If it is an automatic variable like this, create it on the heap via new and see if your symptoms change. If it is created with malloc/new, change it to a stack-based variable and see what happens.

    This can give you some simple yet vital clues as to what is going on. Interestingly enough, if you look at the original code and insert my dodgyIndex test immediately after the for loop (but before any of the output lines) TargetArray[25] reports a value of -1, not 20 as you would expect...however even though the app can make it to the finish line, because of the way the long array is allocated valgrind and electric fence cannot see the bugs. However I altered the test a little to push the array onto the heap by allocating it with new and passing it to the test function, rebuilt and ran it under valgrind once again and got the following output (extraneous output removed):
    Code:
    ==6098== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 21 from 8)
    ==6098== 
    ==6098== 1 errors in context 1 of 4:
    ==6098== Invalid read of size 4 <<== attempt to display TargetArray-[25]
    ==6098==    at 0x8048ECB: testBounds(long*) (boundscheck_main.cpp:35)
    ==6098==    by 0x804909D: main (boundscheck_main.cpp:71)
    ==6098==  Address 0x42ce0d4 is 0 bytes after a block of size 100 alloc'd
    ==6098==    at 0x4025024: operator new[](unsigned int) (vg_replace_malloc.c:258)
    ==6098==    by 0x804908F: main (boundscheck_main.cpp:70)
    ==6098== 
    ==6098== 
    ==6098== 1 errors in context 2 of 4:
    ==6098== Invalid write of size 4 <<== my write of a value to TargetArray[-1]
    ==6098==    at 0x8048E3E: testBounds(long*) (boundscheck_main.cpp:31)
    ==6098==    by 0x804909D: main (boundscheck_main.cpp:71)
    ==6098==  Address 0x42ce06c is 4 bytes before a block of size 100 alloc'd
    ==6098==    at 0x4025024: operator new[](unsigned int) (vg_replace_malloc.c:258)
    ==6098==    by 0x804908F: main (boundscheck_main.cpp:70)
    ==6098== 
    ==6098== 
    ==6098== 1 errors in context 3 of 4:
    ==6098== Invalid write of size 4 <<== OPs write to element TargetArray[25]
    ==6098==    at 0x8048E19: testBounds(long*) (boundscheck_main.cpp:29)
    ==6098==    by 0x804909D: main (boundscheck_main.cpp:71)
    ==6098==  Address 0x42ce0d4 is 0 bytes after a block of size 100 alloc'd
    ==6098==    at 0x4025024: operator new[](unsigned int) (vg_replace_malloc.c:258)
    ==6098==    by 0x804908F: main (boundscheck_main.cpp:70)
    ==6098==
    So depending on your situaion, Valgrind can hand you the bugs on a silver platter or provide a false sense of security.
    Electric fence did a little better and a lot worse; yes it detected the first memory overwrite but didn't tell you where it was but it did through a segfault which stinks if thats all you have but if you ran the same app in GDB the segfault would cause a stack trace dump which would be helpful plus it more or less pointed out the first line with an error on it:

    Code:
    boundscheck_test 1.0
    
      Electric Fence 2.1 Copyright (C) 1987-1998 Bruce Perens.
    Testing: boundscheck
    Test 1: 
    TargetArray[0]: 10
    TargetArray[24]: 10
    
    
    Attempting at assigning values beyond the upper bound...
    
    Program received signal SIGSEGV, Segmentation fault.
    0x08048e79 in testBounds (TargetArray=0xb7ed8f9c) at /home/jeff/dev/bounds/boundscheck_main.cpp:29
    29	      TargetArray[i] = 20; // asigning my fail for element 25
    I know, TMI...
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Code::Blocks Help
    By rakeshkool27 in forum C Programming
    Replies: 0
    Last Post: 01-16-2010, 08:25 AM
  2. library issues in CodeBlocks
    By everlearnin in forum C++ Programming
    Replies: 0
    Last Post: 06-02-2009, 08:44 PM
  3. Codeblocks crashes linux?
    By Shakti in forum Tech Board
    Replies: 1
    Last Post: 03-25-2009, 07:26 AM
  4. Code::Blocks doesn't like my enums and typedefs
    By muehl in forum C++ Programming
    Replies: 19
    Last Post: 02-12-2009, 10:48 AM
  5. Replies: 1
    Last Post: 01-11-2008, 09:34 AM