Valgrind invalid read on FILE* - c++

The following code, when built on ubuntu creates an executable.
#include <stdio.h>
void otherfunc(FILE* fout){
fclose(fout);//Line 4
fout = fopen("test.txt", "w");//Delete contents and create a new file//Line 5
setbuf(fout, 0);//Line 6
}
int main() {
FILE *fout = fopen("test.txt", "r");//Line 10
if (fout) {
//file exists and can be opened
fclose(fout);//Line 13
fout = fopen("test.txt", "a");//Line 14
setbuf(fout, 0);
}
else {
//file doesn't exists or cannot be opened
fout = fopen("test.txt", "a");//Line 19
}
otherfunc(fout);//Line 22
fclose(fout);//Line 24
return 0;
}
When run through valgrind, valgrind gives the following warnings:
==13569== Invalid read of size 4
==13569== at 0x4EA7264: fclose##GLIBC_2.2.5 (iofclose.c:53)
==13569== by 0x400673: main (newmain.cpp:24)
==13569== Address 0x52042b0 is 0 bytes inside a block of size 552 free'd
==13569== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13569== by 0x4EA7362: fclose##GLIBC_2.2.5 (iofclose.c:84)
==13569== by 0x4005CD: otherfunc(_IO_FILE*) (newmain.cpp:4)
==13569== by 0x400667: main (newmain.cpp:22)
==13569== Block was alloc'd at
==13569== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13569== by 0x4EA7CDC: __fopen_internal (iofopen.c:69)
==13569== by 0x400657: main (newmain.cpp:19)
Essentially, it is complaining that the fclose(fout); on Line 24 is closing an already freed memory that was freed on line 4 fclose(fout); within otherfunc(). But the Line 24's fclose(fout); is meant to close the fopen() performed on Line 5.
At any point in time in the code, whenever a fclose() is called, there is always exactly one open fopen(). Why is this then an invalid read as reported by valgrind?

otherfunc takes a file pointer by value. So the value you've assigned at line 5 is lost after returning from otherfunc and when it returns into main the value of fout there remains unchanged. It contains a dangling file pointer value that you've closed at line 4. Therefore a call to close on line 24 will receive an invalid pointer.

Related

Segment Fault 11 with Dynamic C-String being Displayed from Class Function

Dynamic c-string 'textString' causes Segmentation fault 11 when used by a class member function to be displayed.
#include "Text.h"
#include <iostream>
#include <cstring>
using namespace std;
Text::Text(const char* textArray)
{
textLength = strlen(textArray);
char* textString = new char[textLength];
strcpy(textString, textArray);
cout << textString << endl;
}
Text::~Text()
{
delete[] textString;
}
void Text::displayText() const
{
cout << textString << endl;
}
My provided driver:
#include <iostream>
#include "Text.h"
using namespace std;
int main()
{
Text *myString1;
char tvshow[1000];
cout << "\n\nWhat is the most recent TV show you watched?\n";
cin.getline(tvshow, 1000);
myString1 = new Text(tvshow);
cout << "\n\nTV SHOW:\t";
myString1->displayText();
cout << "\t# CHARACTERS:\t" << myString1->getLength() << endl;
return 0;
}
In the Constructor for the Text class, the line cout << textString << endl; works as intended. However, when the main function calls myString1->displayText();, bash ends the program with Segmentation fault: 11.
Any help would be greatly appreciated. Thank you.
Additionaly to what Algirdas says, your other problem is, that you actually don't assign the class member textString (assuming you have one), but shadow it in your constructor.
Change your constructor to something like this:
Text::Text(const char* textArray)
{
textLength = strlen(textArray);
textString = new char[textLength + 1];
strcpy(textString, textArray);
cout << textString << endl;
}
Note the missing char * in front of textString.
How did I spot this?
As with any other segfault, you should learn how to debug. Your best tools are gdb and valgrind. Running this with valgrind gives me:
$ echo franz | valgrind ./a.out
==6222== Memcheck, a memory error detector
==6222== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6222== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==6222== Command: ./a.out
==6222==
What is the most recent TV show you watched?
franz
TV SHOW: ==6222== Invalid read of size 1
==6222== at 0x4C32CF2: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6222== by 0x108DB6: Text::getLength() const (a.cpp:37)
==6222== by 0x108E70: main (a.cpp:51)
==6222== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==6222==
==6222==
==6222== Process terminating with default action of signal 11 (SIGSEGV)
==6222== Access not within mapped region at address 0x0
==6222== at 0x4C32CF2: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6222== by 0x108DB6: Text::getLength() const (a.cpp:37)
==6222== by 0x108E70: main (a.cpp:51)
==6222== If you believe this happened as a result of a stack
==6222== overflow in your program's main thread (unlikely but
==6222== possible), you can try to increase the size of the
==6222== main thread stack using the --main-stacksize= flag.
==6222== The main thread stack size used in this run was 8388608.
==6222==
==6222== HEAP SUMMARY:
==6222== in use at exit: 14 bytes in 2 blocks
==6222== total heap usage: 5 allocs, 3 frees, 77,838 bytes allocated
==6222==
==6222== LEAK SUMMARY:
==6222== definitely lost: 6 bytes in 1 blocks
==6222== indirectly lost: 0 bytes in 0 blocks
==6222== possibly lost: 0 bytes in 0 blocks
==6222== still reachable: 8 bytes in 1 blocks
==6222== suppressed: 0 bytes in 0 blocks
==6222== Rerun with --leak-check=full to see details of leaked memory
==6222==
==6222== For counts of detected and suppressed errors, rerun with: -v
==6222== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
fish: Process 6222, “valgrind” “echo franz | valgrind ./a.out” terminated by signal SIGSEGV (Address boundary error)
You can clearly see, that the crash happens in getLength, because it tries to access address 0x0. When you run this with gdb, you will stop at exactly that point and can see print textString, that it is 0 and not properly initiliazed.
Please read What is a debugger and how can it help me diagnose problems? for further information!
You are witnessing undefined behavior, due to strcpy(textString, textArray); writing out of bounds.
In
Text::Text(const char* textArray)
{
textLength = strlen(textArray);
char* textString = new char[textLength];
strcpy(textString, textArray);
cout << textString << endl;
}
strlen (textArray) returns the length of a null-terminated string pointed at by textArray. Such length doesn't include the null-terminator itself. However, strcpy writes the null-terminator to the destination string. To avoid such an issue, allocate a place for the null-terminator:
Text::Text(const char* textArray)
{
textLength = strlen(textArray);
char* textString = new char[textLength + 1];
strcpy(textString, textArray);
cout << textString << endl;
}
I am assuming that textLengthand textString are member variables of your class (of type size_t and char * respectively). You don't show the definition of your class Text.
You made a mistake in your constructor. This line
char* textString = new char[textLength];
should be
char* textString = new char[textLength+1];
to allow for the trailing '\0' that C strings have. Also you might want to bulletproof your class Text by making sure your write a copy contructor, destructor and assignment operator. Also consider what happens if NULL is passed to Text constructor. Alternatively a better option is to use std::string as a member variable, which means you can do away with the copy constructor, destructor and assignment operator (the compiler generated versions will just work); you can also do away with textLength and you can write a constructor that is member initialised.

Multithread Access violation reading location C++

I have an C++ application that has a main thread and a Poco::Timer to trigger a callback which writes to a file using Poco::FileOutputStream:
FileOutputStream file("test.txt", ios::binary); <-- *Access violation reading location here*
file.write(reinterpret_cast<char *>(&data), sizeof(data));
file.close();
The code always failed at the first line, here is the call stack:
testProject.exe!std::ctype::widen(char _Byte=' ') Line 1716 + 0xf bytes C++
testProject.exe!std::basic_ios >::widen(char _Byte=' ') Line 126 C++
testProject.exe!std::basic_ios >::init(std::basic_streambuf > * _Strbuf=0x038ef700, bool _Isstd=false) Line 135 + 0xa bytes C++
testProject.exe!std::basic_ostream >::basic_ostream >(std::basic_streambuf > * _Strbuf=0x038ef700, bool _Isstd=false) Line 54 C++
testProject.exe!Poco::FileOutputStream::FileOutputStream(const std::basic_string,std::allocator > & path="c:\Projects\TestProject\test.txt", int mode=32) Line 93 + 0xa3 bytes C++
testProject.exe!OPC_Server::OnTimer(Poco::Timer & timer={...}) Line 3656 + 0x13 bytes C++
testProject.exe!Poco::TimerCallback::invoke(Poco::Timer & timer={...}) Line 212 + 0x14 bytes C++
testProject.exe!Poco::Timer::run() Line 197 + 0x19 bytes C++
testProject.exe!Poco::PooledThread::run() Line 200 + 0x15 bytes C++
testProject.exe!Poco::`anonymous namespace'::RunnableHolder::run() Line 57 + 0x17 bytes C++
testProject.exe!Poco::ThreadImpl::runnableEntry(void * pThread=0x00db6afc) Line 207 + 0x20 bytes C++
testProject.exe!_callthreadstartex() Line 348 + 0xf bytes C
testProject.exe!_threadstartex(void * ptd=0x00db6d00) Line 331 C
Tracing into the stack, the timer thread seemed having problem reading the initialization _Byte at the top of the call stack in xlocale internal header:
_Elem __CLR_OR_THIS_CALL widen(char _Byte) const
{ // widen char
return (do_widen(_Byte)); <-- failed: Access violation reading location
}
Second entry in the stack in ios standard header:
_Elem __CLR_OR_THIS_CALL widen(char _Byte) const
{ // convert _Byte to character using imbued locale
const _Ctype& _Ctype_fac = _USE(getloc(), _Ctype);
return (_Ctype_fac.widen(_Byte)); <-- call the top of the stack
}
Third entry in the stack in ios standard header:
protected:
void __CLR_OR_THIS_CALL init(_Mysb *_Strbuf = 0,
bool _Isstd = false)
{ // initialize with stream buffer pointer
_Init(); // initialize ios_base
_Mystrbuf = _Strbuf;
_Tiestr = 0;
_Fillch = widen(' '); <-- call the second entry
But very strangely, the same code runs fine without any error when being used on the main thread.
Is there any permission settings that I need to set for the Poco::Timer to be able to function properly? Or am I missing something very obvious? Thanks for any help.
EDIT: ----------------------
Poco version: 1.7.3
Platform: windows
It turns out that the application exits immediately after the timer is created, but the exit is not cleanly done so it appears that the app is still running and the timer is still ticking, when actually some of the resource has already been released, which causes the error.
MS's _tmain() does something extra than main() apparently.
Sorry it is not _tmain(), but _tmainCRTStartup that is calling _tmain(). When _tmain() exits, other clean up code is run, my project isn't terminated somehow and the application appears still "running".

Visual C++ 2013 std::string memory leak

During development of proprietary app. I have noticed memory leak, related to std::string in a MS Visual C++ 2013, Update 4.
Take a look at the following (basic) code prototype which causes memory leak:
static std::string MemoryLeakTest()
{
static size_t const test_size = 2002;
std::unique_ptr<char[]> result1(new char[test_size]);
std::string result2(result1.get(), test_size);
return result2;
}
calling it by:
std::string const testML = MemoryLeakTest();
std::cout << testML << std::endl;
Am I doing something wrong, or is it a memory leak in a Visual C++ STL?
P.S. this is DebugView output showing mem leak detected by VLD:
[11140] WARNING: Visual Leak Detector detected memory leaks!
[11140] ---------- Block 3 at 0x00A95620: 2002 bytes ----------
[11140] Leak Hash: 0x1DA884B6, Count: 1, Total 2002 bytes
[11140] Call Stack (TID 9568):
[11140] 0x0FF5C260 (File and line number not available): MSVCR120D.dll!operator new
[11140] f:\dd\vctools\crt\crtw32\stdcpp\newaop.cpp (6): TestCpp.exe!operator new[] + 0x9 bytes
[11140] c:\work\testcpp\testcpp.cpp (307): TestCpp.exe!MemoryLeakTest + 0xA bytes
[11140] c:\work\testcpp\testcpp.cpp (401): TestCpp.exe!wmain + 0x9 bytes
[11140] f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c (623): TestCpp.exe!__tmainCRTStartup + 0x19 bytes
[11140] f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c (466): TestCpp.exe!wmainCRTStartup
[11140] 0x75557C04 (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0x24 bytes
[11140] 0x77C4B54F (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x8F bytes
[11140] 0x77C4B51A (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x5A bytes
[11140] Data:
Tried your code with Deleaker and it couldn't find any leak.
Then tried this code:
while (true)
{
std::string const testML = MemoryLeakTest();
std::cout << testML << std::endl;
}
Task Manager shows that memory usage remains the same: no leaks.
I think this is a bug in VLD, you can find that std::unique_ptr really frees the memory, just step into during debugging, look:
~unique_ptr() _NOEXCEPT
{ // destroy the object
_Delete();
}
Go further:
void _Delete()
{ // delete the pointer
if (this->_Myptr != pointer())
this->get_deleter()(this->_Myptr);
}
};
Go further:
void operator()(_Ty *_Ptr) const _NOEXCEPT
{ // delete a pointer
static_assert(0 < sizeof (_Ty),
"can't delete an incomplete type");
delete[] _Ptr;
}
};
Aha, delete[] is called!
The call
std::unique_ptr<char[]> result1(new char[test_size]);
is correct. The tricky part is NOT to write std::unique_ptr<char>, which also compiles and can cause a memory leak (unique_ptr calls delete to release resource. When initialized with new[], we need to instruct unique_ptr to call the correct delete[]).
The std::string constructor call is also OK and it's very unlikely there's a memory leak. The std::string can be initialized from a C-style pointer in the same way.
I don't see any memory leak in your code snippet. How do you know it's a memory leak?

Heap corruption in code

According to the Visual C++ runtime there is a heap corruption when calling free in the destructor. But I don't understand why there is a heap corruption, can anyone explain why? The precise error is:
CRT detected that the application wrote to memory after end of heap buffer.
Also, if I ignore the error the program doesn't crash, it keeps running and when I press a key it returns 0.
The class only contains a constructor and destructor and the private vars FILE* target and char* raw_data.
foo::foo (wchar_t* path)
{
size_t size;
target = _wfopen (path, L"rb+");
if (!target) {
char* error = strerror (errno);
printf ("The file could not be opened: %s\n", error);
_exit (1);
}
fseek (target, 0L, SEEK_END);
size = ftell (target);
fseek (target, 0, SEEK_SET);
raw_data = (char*) malloc (size);
size = fread (raw_data, 1, size, target);
raw_data[size] = '\0';
}
foo::~foo ()
{
fclose (target);
free (raw_data);
}
int main ()
{
nbt* klas = new nbt (L"C:\\Users\\Ruben\\level");
puts ("Success?!");
delete klas;
getchar ();
return 0;
}
When writing the NUL terminator as you do:
raw_data[size] = '\0';
... you are using one byte more than the bytes you allocated. There may be other errors but there is definitely an error on this line -- writing to memory you have not allocated is "undefined behaviour" and could explain the crash you're observing.
One sure problem is this code:
raw_data = (char*) malloc (size);
size = fread (raw_data, 1, size, target);
raw_data[size] = '\0';
You cannot access raw_data[size], because it is beyond the allocated size. Indexed access in C/C++ is zero based. As a result, the last element of raw_data that can be accessed with your existing code is raw_data[size-1]. To be able to set the byte which is at offset size to zero you need to change your malloc to:
raw_data = (char*) malloc (size+1);
Since this is a C++ application, you may want to use streams and new/delete instead of FILE pointers and malloc/free.

new and malloc allocates extra 16 bytes

I'm writing on c++ in VS2010 Windows 7. I try to read file of size 64 bytes. Here's the code:
BYTE* MyReadFile(FILE *f)
{
size_t result;
BYTE *buffer;
long lSize;
if (f == NULL)
{
fputs ("File error", stderr);
exit (1);
}
fseek (f, 0, SEEK_END);
lSize = ftell (f);
rewind (f);
//buffer = (BYTE*) malloc (sizeof(char)*lSize);
buffer = new BYTE[lSize];
if (buffer == NULL)
{
fputs ("Memory error", stderr);
exit (2);
}
result = fread (buffer, 1, lSize, f);
if (result != lSize)
{
fputs ("Reading error",stderr);
exit (3);
}
fclose (f);
return buffer;
}
When I get file size it is 64, but when I allocate memory for it with new BYTE[lSize] I get 80 bytes of space and thus strange sequence ээээ««««««««оюою is added to the end of buffer. Can you please tell me how to handle this?
There is an important difference between the number of bytes you have allocated, and the number of bytes that you see.
If lsize is 64, you have indeed allocated yourself 64 bytes. This does not mean that behind the screen the C++ run time will have asked exactly 64 bytes to Windows. In practice memory managers ask slightly more memory so they are able to do their own homework. Often these extra bytes are allocated BEFORE the pointer you get back from new/malloc so you will never see them.
However, that is not your problem. The problem is that you read 64 bytes from file using fread. There is no way that fread knows what kind of data you are reading. It could be a struct, a char buffer, a set of doubles, ... It just reads these bytes for you.
This means that if the file contains the characters "ABC" you will get exactly "ABC" back. BUT, in C, strings should be nul-terminated, so if you pass this buffer to printf, it will continue to scan memory until it finds a nul-character.
So, to solve your problem, allocate 1 byte more, and set the last byte to the nul character, like this:
buffer = new BYTE[lSize+1];
buffer[lSize] = '\0';
What is behind and above is called sentinel.It is used to check if your code does not exceed boundary of allocated memory.When your program overwrite this values, CRT library will report debug messages when you release your buffer.
Look here : http://msdn.microsoft.com/en-us/library/ms220938%28v=vs.80%29.aspx
Although this may look like a memory problem, its actually a printing problem (as #Mystical pointed out). You need to put a null termination if you are going to print out anything as a string, else memory will be wildy read till one is encountered (which is UB).
Try this instead:
buffer = new BYTE[lSize + 1];
if (buffer == NULL)
{
fputs ("Memory error", stderr);
exit (2);
}
result = fread (buffer, 1, lSize, f);
if (result != lSize)
{
fputs ("Reading error",stderr);
exit (3);
}
buffer[lSize] = '\0';
It'll ensure there is a null terminator at the end of the returned buffer.
When memory is allocated, it is not on a per byte basis. Instead it is allocated in aligned blocks of 8 or 16 bytes (possibly with a header at the start, before the pointer). This is usually not a problem unless you create lots (many millions) of little objects. This doesn't have to be a problem in C and isn't even a major problem in Java (which doesn't support array of objects or objects allocated on the stack).