Valgrind array overflowed inside objects

I have a simple program as shown below.

struct Test
{
    int a[5];
    int b;
};

int main()
{
    Test* t = new Test;
    t->b = 1;
    t->a[5] = 5;          //This is an illegal write
    cout << t->b << endl; //Output is 5
    return 0;
}

      

Launching with Valgrind Memcheck did not report an illegal write in memory.

I noticed that Valgrind claims that the Memcheck tool cannot detect a global or stacked array exceeded, but that array is on the heap, right? It's just that the array is in the object.

Is Valgrind really unable to detect such an error or is there just something wrong? If the former is true, then is there any other tool that can detect this type of error?

=============================================== === ========================

Update:

The compilation command used was g++ -O0 -g main.cc

. The command valgrind

was simple valgrind ./a.out

, which by default should call the tool memcheck

.

Compiler version gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC)

, and valgrind

- valgrind-3.5.0

.

Valgrind output when running this program:

==7759== Memcheck, a memory error detector
==7759== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==7759== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==7759== Command: ./a.out
==7759== 
5
==7759== 
==7759== HEAP SUMMARY:
==7759==     in use at exit: 24 bytes in 1 blocks
==7759==   total heap usage: 1 allocs, 0 frees, 24 bytes allocated
==7759== 
==7759== LEAK SUMMARY:
==7759==    definitely lost: 24 bytes in 1 blocks
==7759==    indirectly lost: 0 bytes in 0 blocks
==7759==      possibly lost: 0 bytes in 0 blocks
==7759==    still reachable: 0 bytes in 0 blocks
==7759==         suppressed: 0 bytes in 0 blocks
==7759== Rerun with --leak-check=full to see details of leaked memory
==7759== 
==7759== For counts of detected and suppressed errors, rerun with: -v
==7759== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)

      

+3


source to share


1 answer


I think the following suggestion you already found:

Memcheck cannot detect every memory error in your program. For example, it cannot detect out of range reads or writes to arrays that are statically allocated or on the stack. But it should detect many errors that can cause your program to crash (for example, cause a segmentation fault).

in the case of your class definition should be interpreted as follows: although the class object is allocated dynamically, the array itself is statically allocated.

I checked several cases:

Valgrind will report an invalid entry if the array is dynamically allocated:

struct Test
{
    int *a;
    int b;
};

int main()
{
    Test* t = new Test;
    t->a = new int[5];
    t->b = 1;
    t->a[5] = 5;          //This is an illegal write
    cout << t->b << endl; //Output is 5
    delete [] t->a;
    delete t;
    return 0;
}

      

An error will also be reported if you change the order of the members to:

struct Test
{
  int b;  
  int a[5];
};

      



This is due to the fact that when trying to write in [5] we will already lag behind the dynamically allocated object.

With the original class definition, if you try to write in [6] - because then we are lagging behind b

, so behind the dynamically allocated object.


Update : gcc sanitizer (I suspect clang does too) detects this from restricted access at runtime by compiling:

g++ -fno-omit-frame-pointer -fsanitize=bounds m.cpp

      

Output:

m.cpp:15:7: runtime error: index 5 out of bounds for type 'int [5]'

      

+3


source







All Articles