使用传入的数组初始化其他数组 [英] Using passed-in array to initialize other array

查看:83
本文介绍了使用传入的数组初始化其他数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试初始化"在类声明中创建的数组,但我不知道自己在做什么错.我知道,当您将数组传递给函数时,它会衰减为指向第一个字符的指针.代码在第二行strcpy()处中断,但是我不确定自己做错了什么(我对strcpy()的经验很少).

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()).

我的代码如下:

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);
}

我的int main()很简单:

My int main() is simply:

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

如果值得注意,numOfChars等于6,应该正确.

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

抛出的异常是:访问冲突写入位置0xCDCDCDCD."

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

推荐答案

在将数据从tmp复制到m_string之前,您没有为m_string分配任何内存.这就是为什么你崩溃了. m_string没有指向有效的内存地址.

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.

由于已经分配了tmp,并且不再使用它,因此可以直接将tmp指针直接分配给m_string,而无需执行其他复制.

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.

此外,请注意,您的while循环正在复制strlen()已经执行的操作,因此您应该只使用strlen().

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

尝试一下:

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

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

可以使用strdup()进行简化(使用free()而不是delete[]进行分配):

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);
}

话虽如此,您的main()正在泄漏内存,因为您没有释放test对象:

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
}

或者简单地:

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

最后,请确保您实施三人制在您的课堂上.您正在管理在析构函数中释放的动态内存,因此在从其他TestClass值创建TestClass值时,还需要一个拷贝构造函数和一个拷贝分配操作来确保m_string的完整性:

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;
}

这篇关于使用传入的数组初始化其他数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆