Using passed-in array to initialize other array

社会主义新天地 提交于 2019-12-25 05:14:28

问题


I am trying to "initialize" an array that I have made in my class declaration and I do not know what I am doing wrong. I understand that when you pass an array into a function, it decays into a pointer to the first character. The code breaks on my second strcpy() line but I am not sure what it is I am doing wrong (I have very little experience with strcpy()).

My code reads as follows:

class TestClass
{
public:
    TestClass(char []);
    ~TestClass();
    void Append(TestClass);

    char* m_string;
};

TestClass::TestClass(char incstring[])
{
    char currentChar = 'a';
    int numOfChars = 0;

    while (currentChar != '\0') {
        currentChar = *(incstring + numOfChars);
        numOfChars++;
    }

    char* tmp = new char[numOfChars-1];
    strcpy(tmp, incstring);
    strcpy(m_string, tmp);
}

My int main() is simply:

int main(){
    TestClass* test = new TestClass("Hello");
}

If it is worth noting, numOfChars is equal to 6, as it correctly should be.

The exception thrown is: " Access violation writing location 0xCDCDCDCD. "


回答1:


You are not allocating any memory for m_string before you copy data from tmp to m_string. That is why you are crashing. m_string is not pointing at a valid memory address.

Since you have already allocated tmp and you are not going to use it anymore, you can just assign the tmp pointer directly to m_string without performing another copy.

Also, note that your while loop is duplicating what strlen() already does, so you should just use strlen().

Try this:

TestClass::TestClass(char incstring[])
    : m_string(new char[strlen(incstring)+1])
{
    strcpy(m_string, incstring);
}

TestClass::~TestClass()
{
    delete[] m_string;
}

Which can be simplified using strdup() instead (use free() instead of delete[] to deallocate it):

TestClass::TestClass(char incstring[])
    : m_string(strdup(incstring))
{
}

TestClass::~TestClass()
{
    free(m_string);
}

With that said, your main() is leaking memory, as you are not freeing the test object:

int main(){
    TestClass* test = new TestClass("Hello");
    //...
    delete test; // <-- add this
}

Or simply:

int main(){
    TestClass test("Hello");
}

And lastly, make sure you implement the Rule of Three in your class. You are managing dynamic memory that is freed in the destructor, so you also need a copy constructor and a copy assignment operation to ensure the integrity of m_string when creating TestClass values from other TestClass values:

class TestClass
{
private:
    char* m_string;

public:
    TestClass(char *incstring = 0);
    TestClass(const TestClass &src);
    ~TestClass();

    void Append(const TestClass &str);
    void Swap(TestClass &Other);

    TestClass& operator=(const TestClass &lhs);
};

TestClass::TestClass(char *incstring)
    : m_string(0)
{
    if (incstring)
    {
        m_string = new char[strlen(incstring)+1];
        strcpy(m_string, incstring);
    }
}

TestClass::TestClass(const TestClass &src)
    : m_string(0)
{
    if (src.m_string)
    {
        m_string = new char[strlen(src.m_string)+1];
        strcpy(m_string, src.m_string);
    }
}

TestClass::~TestClass()
{
    delete[] m_string;
}

void TestClass::Append(const TestClass &str)
{
    if (str.m_string)
    {
        TestClass tmp;
        tmp.m_string = new char[strlen(m_string)+strlen(str.m_string)+1];
        strcpy(tmp.m_string, m_string);
        strcat(tmp.m_string, str.m_string);
        Swap(tmp);
    }
}

void TestClass::Swap(TestClass &Other)
{
    char *ptr = m_string;
    m_string = Other.m_string;
    Other.m_string = ptr;
}

TestClass& TestClass::operator=(const TestClass &lhs)
{
    if (this != &lhs) {
        TestClass(lhs).Swap(*this);
    }    
    return *this;
}


来源:https://stackoverflow.com/questions/43531933/using-passed-in-array-to-initialize-other-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!