Why does valgrind say I've got memory leak at the fclose() call?
#include <stdio.h>
class Stream
{
public:
Stream();
~Stream();
private:
char* pszOutput;
size_t size;
FILE* file;
};
Stream::Stream()
{
file = open_memstream(&pszOutput, &size);
}
Stream::~Stream()
{
fclose(file);
}
int main()
{
Stream s;
return 0;
}
Valgrind report:
==52387== 1 bytes in 1 blocks are definitely lost in loss record 1 of 1
==52387== at 0x4C28CCE: realloc (vg_replace_malloc.c:632)
==52387== by 0x5639CA3: _IO_mem_finish (memstream.c:132)
==52387== by 0x5635956: fclose##GLIBC_2.2.5 (iofclose.c:66)
Does it matter to initialize pszOutput or size? Or maybe I need to add something else?
From : http://linux.die.net/man/3/open_memstream
The open_memstream() function opens a stream for writing to a buffer. The buffer is dynamically allocated (as with malloc(3)), and automatically grows as required. After closing the stream, the caller should free(3) this buffer.
So according to this you need to free(pszOutput) after your file descriptor is closed.
Related
I have distilled by question down to a very simple example where I have a structure constructor that is initializing everything, yet valgrind complains about uninitialized bytes. The culprit seems to be the boolean member of the class, which causes padding bytes to be inserted before the size_t member. What is the right way to initialize those padding bytes so that valgrind doesn't complain?
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define MAX 128
typedef struct foo_struct
{
foo_struct(const std::string& name, bool q = true) : q(q)
{
if (name.size() > MAX)
{
throw std::runtime_error("too big");
}
point_name_size = name.size();
memset(n, 0, sizeof(n));
memcpy(n, name.c_str(), name.size());
}
bool q;
size_t point_name_size;
char n[MAX];
} foo_t;
int main()
{
int fd = open("/tmp/foo", O_WRONLY | O_CREAT, 0666);
if (-1 == fd)
{
throw std::runtime_error("Can't create File Descriptor: " + std::string(strerror(errno)));
}
const foo_t f("hello");
ssize_t written = write(fd, &f, sizeof(f));
std::cout << "wrote " << written << std::endl;
return 0;
}
Compile and run with
g++ try.cpp && valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 ./a.out
The valgrind error is
==11790== Syscall param write(buf) points to uninitialised byte(s)
==11790== at 0x54ED154: write (write.c:27)
==11790== by 0x1093DE: main (in /home/gri6507/tmp/a.out)
==11790== Address 0x1fff000251 is on thread 1's stack
==11790== in frame #1, created by main (???:)
The right way to serialize a data structure into a chunk of bytes to be written to mass storage is to write a serializer that encodes the data into the desired format. Relying on things not specified by the standard (such as the endianness or type sizes) is simply wrong.
There are plenty of serialization libraries available.
What is the right way to initialize those padding bytes so that valgrind doesn't complain?
I'm not sure about 'the right way' to do this, but there are several possibilities.
you create members for the padding and initialize them
struct bar
{
size_t point_name_size;
char n[MAX];
bool q;
bool unused[7] ={};
};
This 'typically' has the same size as your struct on a 64 bit system. See here.
you fill yourself with 0's if you are trivially copyable
struct bar
{
bar()
{
static_assert(std::is_trivially_copyable_v<bar>);
memset(this, 0, sizeof(bar));
}
size_t point_name_size;
char n[MAX];
bool q;
};
I currently have a std::ofstream being created on the stack, and when it allocates off a global operator new that assigns it memory from a pre-allocated buffer the program will crash after main completes citing std::locale0 : line 59. Read Access Violation. nodeptr was 0x... as the program crash point. nodeptr's memory address is a real address. I have no idea why this is happening, and I can only assume it was because I misunderstand what the allocations are actually doing.
This behaviour happens on a release build tested on MSVC Version 19.10.25019 x86, building on debug has the program complete without a crash. Dr. Memory reports no leaks in debug mode.
Minimal Code:
#include <fstream>
#include <cstdlib>
std::uint8_t *byte = static_cast<std::uint8_t*>(malloc(134217728)); // 134217728 = 128 MiB
void *operator new(size_t bytes) throw(std::bad_alloc)
{
return static_cast<void*>(byte); // Tested empirically, and this is only called once so this shouldnt be a cause of a problem
}
void operator delete(void *memory) throw()
{}
int main()
{
std::ofstream out("abc");
free(byte);
}
There are two obvious bugs:
What if operator new is called more than once? What if the constructor of out constructs a sub-object?
You free byte while out is still in scope. When out's destructor runs, you've already returned its memory to the system.
Try this:
#include <fstream>
#include <cstdlib>
std::uint8_t *byte = static_cast<std::uint8_t*>(malloc(134217728)); // 134217728 = 128 MiB
void *operator new(size_t bytes) throw(std::bad_alloc)
{
static int offset = 0;
void * ret = static_cast<void*>(byte + offset);
offset += 16 * ((bytes + 15) / 16);
return ret;
}
void operator delete(void *memory) throw()
{}
int main()
{
{
std::ofstream out("abc");
}
free(byte);
}
It appears as it is a Visual Studio bug regarding custom allocations and std::locale.
Background:
I'm trying to optimize a logging system so that it uses memory-mapped files. I need to provide an std::ostream-like interface so that the logging system can write to that memory.
I have identified std::strstream (which is deprecated though) and boost::iostreams::basic_array_sink could fit my needs.
Now I want to have the logging cyclic, meaning that when the output pointer is near the end of the memory block it should start over at the beginning again.
My question is where would be the best point to start in order to implement this specific behaviour.
I'm rather overwhelmed by the std::iostreams class hierarchy and don't grasp all the internal workings as for now.
I'm uncertain to whether i should/need to derive from ostream, streambuf, or both?
Are these made for being derived from, anyway?
Or using boost:iostreams, would i need to have to write my own Sink?
EDIT:
The following attempt compiles and produces the expected output:
class rollingstreambuf : public std::basic_streambuf<TCHAR>
{
public:
typedef std::basic_streambuf<TCHAR> Base;
rollingstreambuf(Base::char_type* baseptr, size_t size)
{
setp(baseptr, baseptr + size);
}
protected:
virtual int_type overflow (int_type c)
{
// reset position to start of buffer
setp(pbase(), epptr());
return putchar(c);
}
virtual std::streamsize xsputn (const char* s, std::streamsize n)
{
if (n >= epptr() - pptr())
// reset position to start of buffer
setp(pbase(), epptr());
return Base::xsputn(s, n);
}
};
char buffer[100];
rollingstreambuf buf(buffer, sizeof(buffer));
std::basic_ostream<TCHAR> out(&buf);
for (int i=0; i<10; i++)
{
out << "Mumblemumble " << i << '\n';
}
out << std::ends; //write terminating NULL char
Printing the buffer gives:
Mumblemumble 6
Mumblemumble 7
Mumblemumble 8
Mumblemumble 9
(which confirms the roll-over has taken place)
What it does is that it makes the streambuf use the provided buffer as a cyclic output buffer (put area), without ever advancing the buffer window in the output sequence (stream).
(Using terminology from http://en.cppreference.com/w/cpp/io/basic_streambuf)
Now i feel very uncertain about the robustness and quality of this implementation. Please review and comment it.
This is a valid approach. overflow() should return:
traits::eof() or throws an exception if the function fails. Otherwise, returns some value other than traits::eof() to indicate success.
E.g.:
virtual int_type overflow (int_type c)
{
// reset position to start of buffer
setp(pbase(), epptr());
return traits::not_eof(c);
}
xsputn() should probably write the beginning of the sequence to the end of the buffer, then rewind and write the remaining sequence to the front of the buffer. You could probably get away with the default implementation of xsputn() that calls sputc(c) for each character and then overflow() when the buffer is full.
I wrote a C++ class named DCstring similar to String class in Java.
class DCstring
{
public:
TCHAR *string;
DCstring();
DCstring(TCHAR * str);
DCstring in();
}
DCstring::DCstring()
{
string=NULL;
}
//constructor to initialize
DCstring::DCstring(TCHAR* temp)
{
_TINT i=0;
string=(TCHAR*)malloc(_tcslen(temp)*sizeof(TCHAR)+1);
for(;i<_tcslen(temp);i++)
string[i]=temp[i];
string[i]=0;
}
//to get input from user
DCstring DCstring::in()
{
wprintf(L"\n Enter the string :");
TCHAR arr[200],*s;
_getts(arr);
_TINT i=0;
string=(TCHAR*)realloc(string,_tcslen(arr)*sizeof(TCHAR)+1);
for(;i<_tcslen(arr);i++)
string[i]=arr[i];
string[i]=0;
return(*this);
}
This works fine.
I use this DCstring variable inside a struct and reads & writes that struct object into &from a file using fwrite & fread functions.
typedef struct Stud
{
DCstring name;
}stud;
void InsertToFile(stud *temp,FILE *file)
{
(temp->name)=DCstring();
fflush(stdin);
temp->name=(temp->name).in();
fseek(file,0,SEEK_END);
fwrite(&(*head),sizeof(stud),1,file);
}
void Show(stud *temp,FILE *file)
{
rewind (file ) ;
fread ( &temp,sizeof(stud), 1, file ) ;
wprintf ( L"\n%s",temp->name ) ;
}
This code can read and write data for the 1st time.when I reexecute the code and call Show(stud *temp,FILE *file) function,it throws an runtime error/exception.
"Unhandled exception at 0x77c815de in StudentRecord.exe: 0xC0000005: Access violation reading location 0x002850a8".
seems like problem in memory.Help me out.
Apart from the poor implementation of your DCString class (exposed instance variables, lack of destructor, fixed-sized input buffer, and some more) you have failed to understand that writing an instance of your struct stud won't, in fact, write the contents of the data pointed to by stud.name.string.
struct stud contains an instance of DCString however the memory used to store the string data is on the heap (which you allocated using malloc()); your code is writing the pointer to the allocated memory, which will be meaningless when you read it back in (certainly in a different session).
You need to provide a read/write DCString method, which is passed a FILE * (better would be to use istream and ostream, given this is C++) which reads/writes the string contents, allocating new memory during the read.
The problem is here:
public:
TCHAR *string;
This writes out a pointer to the string, so when you read back in you get a pointer that doesn't point to any data, thus your access violation. This question, for instance, discusses serialisation, which is what you probably want to do.
Furthermore:
fflush(stdin);
Is undefined behaviour.
Yet furthermore, you should really use C++ std::string and std::i/ofstream.
EDIT I just noticed:
wprintf ( L"\n%s %d %c",temp->name ) ;
You don't have anything matching the %d and %c parameters.
Im am a c programmer trying to begin a new phase of my life in c++ (i know i am still using printf below, but that because formatting is so easy). I am looking to print out the first byte of a datafile from a member function of an object. I think my streambuffer is being destroyed before I can read it's data but I'm lost as to what to do.
My class looks like the following
class MyParser {
MyParser(string filepath);
void readHeader();
streambuf *pbuf;
long size;
}
My constructor opens the file, gets the buffer out, outputs the first byte and returns. (I think pbuf is dying at the end of this code). This code outputs First Byte (in constructor): 0x8C
MyParser::MyParser(string filepath) {
ifstream file(filepath.c_str(), ios::in | ios::binary)
pbuf = file.rdbuf();
size = pbuf->pubseekoff(0,ios::end,ios::in);
pbuf->pubseekpos(0,ios::in);
unsigned char byte = pbuf->sgetc();
printf("First Byte (in constructor): 0x%02X\n", byte);
return;
}
My read header is dumping the first byte, but based on the output all is see is First Byte (in readHeader): 0xFF
void MyParser::readHeader() {
unsigned char byte = pbuf->sgetc();
printf("First Byte (in readHeader): 0x%02X\n", byte);
}
My main simply creates a parser and tries to readHeader
void main() {
MyParser parser("../data/data.bin");
parser.readHeader();
}
I think the solution to my problem is to create a new streambuffer but new streambuf(file.rdbuf()) isn't working for me. Any advice?
Your program has undefined behavior: the stream buffer you keep is owned by the std::ifstream you open in body of you constructor. When this object dies, the stream buffer is released as well. The easiest approach to avoid this problem is to have your std::ifstream be a member of your class: this binds the life-time of the stream to your object. It may also be easier to use the std::istream interface for your parsing rather than the somewhat awkward std::streambuf interface.
If you really want to just use a stream buffer, you can allocate a std::filebuf using new filebuf and the open() the file stream directly. To keep a pointer to it, you would probably use std::unique_ptr<std::filebuf> (or std::auto_ptr<std::filebuf> if you are not using C++ 2011). Using the pointer class arranges for automatic release of the object. Of course, the pointers would still be members of your class to get the life-times right.
Your attempt to copy a stream buffer didn't work because stream buffers are not copyable. You'd need to create the file buffer directly:
MyParser::MyParser(std::string const& filename)
: pbuf(new std::filebuf)
{
this-pbuf->open("whatever", std::ios_base::in);
...
}
You need some new C++ teaching material, because (sorry) but this is just so wrong. You need to declare the filestream as a member, there's no need for any new anywhere in this program, and pretty much nobody, ever, needs to deal with streambuf.
class MyParser {
std::ifstream file;
public:
MyParser(string filepath) {
file.open(filepath, std::ios::in | std::ios::binary );
char byte;
file.read(sizeof(byte), &byte);
printf("First Byte (in constructor): 0x%02X\n", byte);
}
void readHeader() {
char byte;
file.read(sizeof(byte), &byte);
printf("First Byte (in readHeader): 0x%02X\n", byte);
}
};