繁体   English   中英

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

[英]initializing char* a = new char[size] does not work

我在初始化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 = new char[mSize]初始化了mString成员变量。 但它并没有像我想象的那样工作。

任何人都可以启发我我的代码有什么问题并修复它吗?

mString不是以 NUL 结尾的。

您正在检查\\0 a构造函数参数。 但是您没有分配mString将相同的\\0放在那里,并且不要从a复制\\0

因此,生成的mString未正确以 NULL 结尾,并且会在结束后读取。

超出分配结束的读取是未定义的行为。 在特定情况下,很可能mString会输出直到某个意外为零,或者会发生崩溃。

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

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

while (a[mSize++])
{
}

或者干脆:

mSize = strlen(a) + 1;

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

您也没有遵循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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM