Hello,

I have a derived class, that I'm trying to delete. This causes a segmentation error, though.

I'm fully aware of the virtual destructor thang, but I'm using it all the way around, and still this issue occurs.

I'll post my headers only, please tell if more is required.

DataStream.h

class DataStream
    {
    public:

	DataStream(const ACCESS_MODE& access, const String& name = "") : m_Access(access), m_Name(name)
	{
	};

	virtual ~DataStream(){}

	virtual size_t read(void* buffer, const size_t& count) = 0;

	virtual size_t write(const void* buffer, const size_t& count)
	{
	    return 0;
	}

	virtual void close() = 0;

	const String& getName()
	{
	    return m_Name;
	}

	const ACCESS_MODE& getAccessMode()
	{
	    return m_Access;
	}

	const size_t& getSize()
	{
	    return m_Size;
	}

	bool isReadable()
	{
	    return m_Access != ACCESS_NONE;
	}

	bool isWriteable()
	{
	    return m_Access == ACCESS_WRITE;
	}

	virtual String readAsString()
	{
	    char* buf = new char[m_Size+1];
	    read(buf, m_Size);
	    buf[m_Size] = '\0';
	    
	    String ret;
	    ret.insert(0, buf, m_Size);
	    
	    delete buf;
	    
	    return ret;
	}

    protected:

	size_t	    m_Size;
	ACCESS_MODE m_Access;

    private:
	
	String	    m_Name;

    };

FileSystemDataStream.h

#include "DataStream.h"
class FileSystemDataStream : public DataStream
    {
    public:

	FileSystemDataStream(std::fstream* stream, bool autoFree = true, const String& name = "");

	FileSystemDataStream(std::ifstream* stream, bool autoFree = true, const String& name = "");
	
	virtual ~FileSystemDataStream(){} // tried having it calling close() too.

	size_t read(void* buffer, const size_t& count);

	size_t write(const void* buffer, const size_t& count);

	void close();
	
    private:

	void _calculateSize();

	bool m_AutoFree;

	std::istream*  m_IStream;
	std::fstream*  m_OStream;
	std::ifstream* m_ReadOnlyStream;

    };

The object is allocated by a factory:

DataStream* Factory::open(const String& filename) const
    {
        std::fstream* stream = new std::fstream;
        stream->open((m_Path+filename).c_str(), std::ios::in | std::ios::binary);

        if(stream->fail())
        {
            delete stream;
            return NULL;
        }

        FileSystemDataStream* dstream = new FileSystemDataStream(stream, true, filename);
        return dstream;
    }

And then deleted right afterwards - result: segmentation fault.

I hope anyone can tell me why. I've been looking around to solve this issue for some weeks now, but I'm ending up with too many commented out delete calls ^^.

Thank you in advance!

Recommended Answers

All 4 Replies

If it were my problem I would copy everything into a new folder and start deleting things. For example:

bool isWriteable()
	{
	    return m_Access == ACCESS_WRITE;
	}

surely doesn't have anything to do with the problem. Once you've done all you can do, I bet you will have a < 20 line program on your hands. This will either point you directly to the source of the problem, or allow someone here to take a quick look.

I see two problems:
1. You're using delete (instead of delete[]) on buf, even though the array was created with new[].

2. In FileSystemDataStream::open you're returning an object created with new as a regular pointer (instead of auto_ptr) which opens the gates to the realm of potential double deletes and memory/resource leaks. For example, where are you deleting the stream passed to the FileSystemDataStream constructor? The most logical place for that (the destructor) doesn't contain any code.

It would also help if you told us which line causes the segmentation fault.

Hi.
The issue is resolved.
Who'd guessed that I some months ago made the close() method call delete? No wonder that it crashes when I then afterwards call delete manually.

I see two problems:
1. You're using delete (instead of delete[]) on buf, even though the array was created with new[].

2. In FileSystemDataStream::open you're returning an object created with new as a regular pointer (instead of auto_ptr) which opens the gates to the realm of potential double deletes and memory/resource leaks. For example, where are you deleting the stream passed to the FileSystemDataStream constructor? The most logical place for that (the destructor) doesn't contain any code.

It would also help if you told us which line causes the segmentation fault.

Thank you for your reply, much appreciated.

I did notice the first thing too :) Just a little typo.
I AM deleting the filestreams in FileSystemDataStream::close().
- This function is also the one calling the destructor.

Debugger just told that the seg error occurd on delete operand.
Which makes sense, since I nearly always called close() and then delete afterwards, which is a multi-delete.

To make things more dramatic, in my attempt to resolve this issue, I put the close() call in the destructor. That's like an infinite loop of segmentation errors? No debbuger info and an irresponsive application was result. But that kicked me on the way to remember.

Should have made the destructor private from the start, human mistake this was :)

Thank you anyway.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.