Click here to Skip to main content
15,881,803 members
Please Sign up or sign in to vote.
3.50/5 (2 votes)
See more:
It's been a long time since I programmed in C++ and I wanted to run a couple of functions by the community just to ensure that my line of thought is correct.

These constructors are supposed to, in theory, accept inputs differing in size or type and then save them to an allocated byte array in the class to be worked on after. I am working towards them being able to accept 8, 16, 32, and 64 bit lengths.

C++
<MyClass.h>

Class MyClass{
private:
__int8* InputBuffer;
__int8* OutputBuffer;
public:
MyClass(__int8*);
MyClass(__int16*);
MyClass(__int32*);
MyClass(__int64*):
~MyClass();
//Other Functions
}

<MyClass.cpp>

MyClass::~MyClass()
{
	if ( this->InputBuff != nullptr ) { _freea(this->InputBuff); }
	if ( this->OutputBuff != nullptr ) { _freea(this->OutputBuff); }
}

MyClass::MyClass(__int8* Source)
{
	void *p = nullptr;
	__int64 size = _msize(Source);

	p = _malloca(size);

	if (p != nullptr) 
		memcpy_s(p, size, Source, size);
	else
		return;
			
	this->InputBuff = (__int8*) p;
}

MyClass::MyClass(__int16* Source)
{
	void *p = nullptr;
	__int64 size = _msize(Source) / sizeof(__int16);

	p = _malloca(size * sizeof(__int16));

	if ( p != nullptr) 
		memcpy_s(p, size * sizeof(__int16), Source, size);
	else
		return;
		
	this->InputBuff = (__int8*) p;
}


I'm just looking for your 2 cents here so that I'm not totally messing this up before writing the rest of the class (and the rest of the project).
Posted
Comments
Pascal-78 9-Aug-13 17:04pm    
Why using 4 constructor, when 1 is enough?
_msize will give the size of the memory block as byte and it uses void* as argument type.
just allocate a new block of the same size and copy it.
MyClass::MyClass(void* Source)
{
__int64 size = _msize(Source);
InputBuff = _malloca(size);
if(InputBuff!=NULL)
memcpy_s(InputBuff, size, Source, size);
}

One more thing : returning from a constructor without initializing all the members is not a good idea, OutputBuff is never initialized and InputBuff is initialized only if memory is allocated.
Foothill 9-Aug-13 17:13pm    
Ah, good point. Thanks.

1 solution

alloca() variants allocate from the stack and the returned pointer goes out of scope at latest when you leave th function in which you called the alloca() function. you should use malloc(). Don't initialize anything in the constructor that can fail. If you want to put complex initializer code to the constructor then do it only if the error can be handled locally or if you can store the error into a member variable and later you check it. A better alternative to this is just initializing the member variables with default values and calling later an Init() method on the object. This has an additional benefit in contrast to the "initialization in constructor" solution: In the constructor it is discouraged to call virtual methods while in the Init() can do that easily. Instead of using __intXX Visual C++ specific fix-width integer types include <stdint.h> and use intXX_t constants, this is a portable way. Using _msize() is also rare, don't use this function. What if I pass you a pointer that isn't allocated on the heap or even if it is on the heap I pass you a pointer that points to the middle of the allocated block and not to the beginning? Instead of passing a pointer and using _msize pass in a (const void*) plus a size parameter, this is the standard when working with binary data in buffers.

C++
#include <stdint.h>

class MyClass
{
public:
    // not recommended
    MyClass(const void* source)
        : m_InputBuffer(NULL)
    {
        // no error checking!
        Init(source);
    }

    // not recommended
    MyClass(const void* source, size_t source_size)
        : m_InputBuffer(NULL)
    {
        // no error checking!
        Init(source, source_size);
    }

    // not recommended
    bool Init(const void* source)
    {
        return Init(source, _msize((void*)source));
    }

    bool Init(const void* source, size_t source_size)
    {
        void* p = malloc(source_size);
        if (!p)
            return false;
        memcpy(p, source, source_size);
        m_InputBuffer = (int8_t*)p;
        return true;
    }

private:
    int8_t* m_InputBuffer;
};
 
Share this answer
 
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900