初始化char * a = new char [size]不起作用

时间:2019-01-12 04:34:26

标签: c++

我在初始化char* a = new char[size]时遇到问题。这是我的代码。

class Practice
{
public:
    Practice(const char* a);
    ~Practice();

    const char* getString() const;

private:
    char* mString;
    int mSize;

};

#include "Practice.h"

Practice::Practice(const char * a)
    :mSize(0)
    ,mString(nullptr)
{
    while (a[mSize] != '\0')
    {
        mSize++;
    }

    mString = new char[mSize];

    for (int i = 0; i < mSize; i++)
    {
        mString[i] = a[i];
    }

}

Practice::~Practice()
{
    delete[] mString;
}

const char* Practice::getString() const
{
    return mString;
}

int main()
{
    Practice p("Hello");

    std::cout << p.getString() << std::endl;

    return 0;
}

我希望结果是Hello

但是结果就像Hello²²²²▌▌▌▌▌▌▌■a%{▌

我以为我通过mString初始化了mString = new char[mSize]成员变量。但这没有按照我的想法工作。

有人能启发我我的代码有什么问题并修复它吗?

4 个答案:

答案 0 :(得分:5)

mString不是NUL终止的。

答案 1 :(得分:1)

您正在检查a的{​​{1}}构造函数参数。但是您没有分配\0来放置相同的mString,也不要从\0复制\0

因此,生成的a不能正确地以NULL结尾,并且将被读取到结尾。

读取超出分配的末尾是未定义的行为。在特定情况下,很可能mString会一直输出直到意外的零,否则会发生崩溃。

答案 2 :(得分:1)

while (a[mSize] != '\0')
{
    mSize++;
}

这将mSize设置为等于a的长度,但不包括结尾的'\0'。您应该在副本中包含终止符:

while (a[mSize++])
{
}

或简单地:

mSize = strlen(a) + 1;

答案 3 :(得分:0)

您并没有将mString数据终止于null,但是当您将其传递给std::cout时,它有望被终止于null。如果没有该终结符,std::cout会读入周围的内存,直到遇到随机的空字节(或由于读取访问错误而崩溃)。这就是为什么您看到std::cout在数据之后输出随机垃圾的原因。

您还没有遵循Rule of 3/5/0,因为您缺少默认构造函数,复制和移动构造函数以及复制和移动分配运算符。

尝试一下:

class Practice
{
public:
    Practice(const char* a = nullptr);
    Practice(const Practice &src);
    Practice(Practice &&src);
    ~Practice();

    Practice& operator=(Practice src);

    const char* getString() const;

private:
    char* mString;
    int mSize;
};

#include "Practice.h"
#include <utility>

Practice::Practice(const char * a)
    : mSize(0)
    , mString(nullptr)
{
    if (a)
    {
        while (a[mSize] != '\0')
        {
            ++mSize;
        }
    }

    mString = new char[mSize + 1];

    for (int i = 0; i < mSize; ++i)
    {
        mString[i] = a[i];
    }

    mString[mSize] = '\0';
}

Practice::Practice(const Practice &src)
    : mSize(src.mSize)
    , mString(nullptr)
{
    mString = new char[mSize + 1];

    for (int i = 0; i < mSize; ++i)
    {
        mString[i] = src.mString[i];
    }

    mString[mSize] = '\0';
}

Practice::Practice(Practice &&src)
    : mSize(src.mSize)
    , mString(src.mString)
{
    src.mString = nullptr;
    src.mSize = 0;
}

Practice::~Practice()
{
    delete[] mString;
}

Practice& Practice::operator=(Practice src)
{
    std::swap(mString, src.mString);
    std::swap(mSize, src.mSize);
    return *this;
}

const char* Practice::getString() const
{
    return mString;
}

#include <iostream>
#include "Practice.h" 

int main()
{
    Practice p("Hello");

    std::cout << p.getString() << std::endl;

    return 0;
}