0
void Example1( char* ArrayA, unsigned int Length )
{
    if( ArrayA == 0 )
    {
        ArrayA = new char[ Length + 1 ];
        // Fill it with 2 - whatever
        ::memset( ArrayA, 0x02, sizeof( char ) * Length );
        ArrayA[ Length ] = '0\n';
    }
    // Do whatever with ArrayA

    // Clean-Up
    // Error occurs
    delete [ ] ArrayA;
};

void Example2( char* ArrayB, unsigned int Length )
{
    bool IsDynamic = false;
    if( ArrayB == 0 )
    {
        ArrayB = new char[ Length + 1 ];
        // Fill it with 2 - whatever
        ::memset( ArrayB, 0x02, sizeof( char ) * Length );
        ArrayB[ Length ] = '0\n';
        IsDynamic = true;
    }
    // Do whatever with ArrayA

    // Clean-Up
    // Have to check...
    if( IsDynamic )
        delete [ ] ArrayB;
};


int main( void )
{
    Example1( "\x01\x02\0x03", 3 ); // Example1 WILL NOT* declare ArrayA as a dynamic array - ERROR (caused by deleting non dynamic array)

    Example2( 0, 3 ); // ArrayB will be a dynamic array - OK
    Example1( 0, 3 ); // OK

    Example2( "\x04\x05\0x06", 3 ); // ArrayB isn't a dynamic array - OK

    return ( 0 );
};

The problem occurs when attempting to delete char* ArrayA in function Example1 because ArrayA is not a dynamic array. It will only be a dynamic array if it is equal to zero/null. So, to resolve that I created a similar function - Example2. The only difference is that Example2 has a boolean that checks to see if char* ArrayB is a dynamic array or not.

I know what I am doing is either incorrect or "noobish". So please help me. I will learn from my mistake.

How would you do it?

void Example3( char* ArrayC, unsigned int Length );
3
  • Is there a reason for you to not use std::vector<char>? Commented Feb 28, 2013 at 9:41
  • @Zeta Is it okay to use that when programming a dll? Commented Feb 28, 2013 at 9:44
  • 1
    I't not OK to delete "outer" data within dll, because of different memory managers Commented Feb 28, 2013 at 9:45

3 Answers 3

1

Maybe you could use this:

void Example2( char* ArrayB, unsigned int Length )
{
    std::vector< char > internalArray;
    if ( ArrayB != 0 )
    {
        internalArray.assign( ArrayB, ArrayB + Length );
    }
    else
    {
        internalArray.resize( Length, 0x2 );
    }
    // Do whatever with internalArray !!! <-------

    // No (!!!) clenup need
};
Sign up to request clarification or add additional context in comments.

3 Comments

Why this: internalArray.resize( Length, 0x2 );
"Why this: internalArray.resize( Length, 0x2 );" - according to your ::memset( ArrayB, 0x02, sizeof( char ) * Length );
BTW, I think, that it would be a good idea to add const to char* ArrayB
0

I know what I am doing is either incorrect or "noobish". So please help me.

My overall recommendation would be to move from using C arrays to using std::vector instead.

5 Comments

Is that the only way? Should I be using std:: if I am programming a dll?
@user2117427 there is no "only way". However you will just be giving yourself headaches by trying to solve a problem this way while a standard ans well tested solution as std::vector exists. And yes, it can be used wherever you want.
@user2117427 If you are using C++, you should hardly ever have to deal with dynamic allocation and memory management yourself. If you find yourself doing that, then you've almost certainly gone wrong. It is always worth stepping back and looking carefully at what the standard library has to offer.
@SirDarius Maybe it's not a good idea to use std::vector in interface of dll ? What will be, if main app and dll use different implementation of STL ?
@borisbn in this context, yes indeed, there is a certain risk. But in any way, in the case of those functions, it is even worse because memory allocated in a different module might not be free'able in the dll (different runtime version, etc) and cause crashes.
0

Your example1 is definitely bad, since it tries to free an array that isn't dynamically allocated - that is NEVER right. As explained elsewhere, if you call across a DLL boundary, you may also have different allocators, so if the memory was not allocated where it is being deleted, things will go wrong. Let whoever allocated it delete it. Preferrably by using already existing standard functionality, such as std::vector

Your example2 only uses delete on something that was created within the function, which is perfectly fine. It doesn't try to delete something that it doesn't know is allocated in the same allocator. Yet, a std::vector would certainly be easier to handle.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.