tags:

views:

118

answers:

4

Hi all,

This is my first year learning C++ so bear with me. I am attempting to dynamically allocate memory to the heap and then delete the allocated memory. Below is the code that is giving me a hard time:

// String.cpp
#include "String.h"

String::String() {}

String::String(char* source)
{
 this->Size = this->GetSize(source);
 this->CharArray = new char[this->Size + 1];
 int i = 0;
 for (; i < this->Size; i++) this->CharArray[i] = source[i];
     this->CharArray[i] = '\0';
}

int String::GetSize(const char * source)
{
 int i = 0;
        for (; source[i] != '\0'; i++);
        return i;
}

String::~String()
{
 delete[] this->CharArray;
}

Here is the error I get when the compiler tries to delete the CharArray:

0xC0000005: Access violation reading location 0xccccccc0.

And here is the last call on the stack:

msvcr100d.dll!operator delete(void * pUserData) Line 52 + 0x3 bytes C++

I am fairly certain the error exists within this piece of code but will provide you with any other information needed. Oh yeah, using VS 2010 for XP.

Thanks for any and all help!

Edit: Heres my String.h

// String.h - string class
#pragma once

#define NOT_FOUND -1

class String
{
public:
    String();
    String(char* source);
    static int GetSize(const char * source);
    int Find(const char* aChar, int startPosition = 0);
    ~String();
private:
    char* CharArray;
    int Size;
};
A: 

I think @dash-tom-bang is correct. You're probably copying String and then deleting its data twice. I'll keep my old answers here for reference, though.

You're going to need to post the code that uses String, but I can notice a few problems here:

  1. What if source is NULL in the constructor? Immediately you have a Null Pointer Exception. What's worse, if you get this exception, the destructor will attempt to delete memory that was never allocated. This could cause the error described above if you're using try...catch.

  2. GetSize should not be a member function of String because it doesn't use any member variables. At the very least it should be static.

rlbond
`std::string` doesn't like being passed a `NULL` pointer either ...
Peter Kovacs
… which is to say, it's safe to assume nobody passes you a NULL pointer unless you say they can. Also, by default operating exceptions such as NULL access do not cause C++ exceptions; they cause immediate termination.
Potatoswatter
+2  A: 
String::String(): CharArray( 0 ) {}

You're not initializing CharArray in every constructor, so in some cases you're deleting an uninitialized pointer.

Peter Kovacs
+5  A: 

Change your default ctor; given the error you're getting, the delete call is trying to delete a pointer that has never been initialized.

String::String() : Size(0), CharArray(NULL) {}

Also, beware of the "copy constructor". You might want to make it private just to be sure you're not triggering it implicitly. (It doesn't need to be implemented if you don't intend to call it, just stick the function prototype into your class definition.) Might as well similarly "disable" the assignment operator.

class String
{
   // other stuff

private:
    String(String&);
    String& operator=(String&);
};

This addition fulfills the "Rule of Three," which says that if any class needs a destructor, a copy constructor, or an assignment operator, it probably needs all three.

Edit: see http://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29

dash-tom-bang
Thanks for the info! I'll try this out along with the advice above and will let you guys know if it resolves my issue.
Pooch
Your collective advice about initializing the members in the constructor solved my original issue. I was then receiving another error which was the result of not properly implementing the '=' operator. Hah! Guess the Rule of Three exists for a reason. Thanks again all for the help!
Pooch
LOL, indeed the rule of three explained a lot to me before I truly came to embrace it. :)
dash-tom-bang
A: 

You have multiple constructors, but only 1 of them calls new. Your destructor always calls delete so there is your error.

Michael Dorgan