0

I am loking for free tool to Visual Studio 2015, which could control accessing to memory. I found just this article (https://msdn.microsoft.com/en-us/library/e5ewb1h3%28v=vs.90%29.aspx?f=255&MSPPError=-2147217396), which controls just memory leaks - its fine, but not enought. When I create array, and access out of that array, I need to know it. For example this code:

int* pointer = (int*)malloc(sizeof(int)*8);
for (int a = 0;a <= 8;a++)
    std::cout << *(pointer+a) << ' ';
free(pointer);
_CrtDumpMemoryLeaks();

This example will not throw exception, but still it access to memory, which is out of allocated space. Is tool for Visual Studio 2015, which will tell mi about it? Something like valgrind.
Thank you.

Patrik Valkovič
  • 706
  • 7
  • 26
  • With proper flags enabled (which are enabled by default: /GS), you'll have a detection if you *write* to the buffer, not if you *read* from it. So for example if you add `*(pointer+a)=0`, then you will get a "heap corruption detected" assert. – Simon Mourier Nov 28 '15 at 11:33
  • @Simon Mourier: From the documentation it doesn't seem as `/GS` can detect a buffer overrun for a dynamically allocated buffer. – Cheers and hth. - Alf Nov 28 '15 at 16:22
  • @Cheersandhth.-Alf - yes it can since 2003 (http://www.codeguru.com/cpp/cpp/cpp_mfc/buffers/article.php/c8361/Visual-C-Protecting-Against-Buffer-Overruns-with-the-GS-Switch.htm) and got improved over time (just google on it). But, add `*(pointer+a)=0` to Patrik's code and see it by yourself. – Simon Mourier Nov 29 '15 at 08:51
  • @SimonMourier: Please quote exactly what you mean supports your contention. – Cheers and hth. - Alf Nov 29 '15 at 15:58
  • @SimonMourier: Testing with Visual C++ 2015 did not support your claim: the buffer overrun was not detected. Here's an [image of the tool usage](http://i.imgur.com/t17fEMZ.png). – Cheers and hth. - Alf Nov 29 '15 at 23:39
  • @Cheersandhth.-Alf - please fully read my comments. I'm talking about *writing*, not only *reading* to the buffer. Add that line `*(pointer+a)=0` to the loop and you'll see it works. Otherwise I would have provided a full answer, not a comment. – Simon Mourier Nov 30 '15 at 06:27
  • @SimonMourier: The screenshot I linked to involves writing. So apparently there is at least one case where /GS doesn't detect buffer overflow for a dynamically allocated buffer, contrary to your claim. How did you manage to not see that it's writing? – Cheers and hth. - Alf Nov 30 '15 at 06:50
  • @Cheersandhth.-Alf - oh sorry missed you changed the main line. Here is what I get: http://snag.gy/96XCu.jpg I just chose all defaults I believe (but x64, and using VS IDE, not from command line) – Simon Mourier Nov 30 '15 at 07:25
  • I tried the 64-bit compiler, invocation `cl foo.cpp /MD /GS /D DEBUG /Feb`, but it still does not detect the overflow. There's some discussion about how `/GS` works [here on SO](http://stackoverflow.com/questions/32511862/how-does-visual-studio-2013-detect-buffer-overrun). Apparently, in addition to cookie checking, it can perform simple index range checking when the array size is known. But how to make it actually *do* something, huh. Mystery… – Cheers and hth. - Alf Nov 30 '15 at 08:02

1 Answers1

1

You can replace the given Microsoft'ish code

int* pointer = (int*)malloc(sizeof(int)*8);
for (int a = 0;a <= 8;a++)
    std::cout << *(pointer+a) << ' ';
free(pointer);
_CrtDumpMemoryLeaks();

… with this:

{
    vector<int> v( 8 );
    for( i = 0; i <= 8; ++i )
    {
        cout << v.at( i ) << ' ';
    }
}
_CrtDumpMemoryLeaks();

And since there's no point in checking for memory leaks in that code (indeed the exception from the attempt to access v[8] ensures that the _CrtDumpMemoryLeaks() statement is not executed), you can simplify it to just

vector<int> v( 8 );
for( i = 0; i <= 8; ++i )
{
    cout << v.at( i ) << ' ';
}

Now, it's so long since I've been checking for indexing errors etc. that I'm no longer sure of the exact magic incantations to add checking of ordinary [] indexing with g++ and Visual C++. I just remember that one could, at least with g++. But anyway, the practical way to go about things is not to laboriously check indexing code, but rather avoid manual indexing, writing

// Fixed! No more problems! Hurray!

vector<int> v( 8 );
for( int const value : v )
{
    cout << value << ' ';
}

About the more general aspect of the question, how to ensure that every invalid memory access generates a trap or something of the sort, that's not generally practically possible, because the granularity of memory protection is a page of memory, which in the old days of Windows was 4 KB (imposed by the processor's memory access architecture). It's probably 4 KB still. There would just be too dang much overhead if every little allocation was rounded up to 4K with a 4K protected page after that.

Still I think it's done for the stack. That's affordable: a single case of great practical utility.

However, the C++ standard library has no functionality for that, and I don't think Visual C++ has any extensions for that either, but if you really want to go that route, then check out the Windows API, such as VirtualAlloc and friends.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • Yes, I could use vector, but vector is more expensive than just allocating memory. More over, replace vector on every place, when I using memory, is quite overkill. I know that probably everytime on every machine, when I run this code, it will not throw exception, but valgrind could recognise this. I found some ulities, but they are non free (http://www.cprogramming.com/tutorial/memory_debugging_parallel_inspector.html). Mainly I need this to school, where accessing out of allocated memory is controled. – Patrik Valkovič Nov 27 '15 at 22:12
  • `std::vector` is more expensive in a checked build, a debug build. To measure performance, measure your release build. And as always in questions of performance, do **measure**. ;-) – Cheers and hth. - Alf Nov 27 '15 at 22:14
  • And also, we have banned using STL in our school works. – Patrik Valkovič Nov 27 '15 at 22:26
  • @PatrikValkovič: Ally yourself with others. Tell your teacher you can't make good progress learning to play the piano if you are not allowed to use a tuned one, but is forced to play only those with mainly sour notes. It's just plain silly and *very unproductive* to not use the standard library. – Cheers and hth. - Alf Nov 27 '15 at 22:35
  • Note there is a decent level of protection from Visual Studio and Windows combined when *writing* to invalid memory access. – Simon Mourier Nov 28 '15 at 11:37