简体   繁体   English

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

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

I have a problem about initializing char* a = new char[size] .我在初始化char* a = new char[size]遇到问题。 Here is my code.这是我的代码。

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

I expected the result is Hello .我预计结果是Hello

But the result was like Hello²²²²▌▌▌▌▌▌▌■a%{▌ .但结果就像Hello²²²²▌▌▌▌▌▌▌■a%{▌

I thought I initialized the mString member variable through mString = new char[mSize] .我以为我通过mString = new char[mSize]初始化了mString成员变量。 But it was not working the way I thought.但它并没有像我想象的那样工作。

Can anybody enlighten me what's wrong with my code and fix it?任何人都可以启发我我的代码有什么问题并修复它吗?

mString不是以 NUL 结尾的。

Your're checking a constructor parameter for \\0 .您正在检查\\0 a构造函数参数。 But you are not allocating mString to put the same \\0 there, and don't copy \\0 from a .但是您没有分配mString将相同的\\0放在那里,并且不要从a复制\\0

So, resulting mString is not properly NULL-terminated and it would be read beyond end.因此,生成的mString未正确以 NULL 结尾,并且会在结束后读取。

Reading beyond end of allocated is undefined behavior.超出分配结束的读取是未定义的行为。 In particular case, it is likely that either mString would output until some accidental zero, or crash would occur.在特定情况下,很可能mString会输出直到某个意外为零,或者会发生崩溃。

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

This sets mSize equal to the length of a , excluding the terminating '\\0' .这将mSize设置mSize等于a的长度,不包括终止'\\0' You should include the terminator in your copy:您应该在副本中包含终止符:

while (a[mSize++])
{
}

or simply:或者干脆:

mSize = strlen(a) + 1;

You are not null-terminating your mString data, but it is expecting to be null-terminated when you pass it to std::cout .您不是空终止您的mString数据,但是当您将其传递给std::cout时,它期望以空终止。 Without that terminator, std::cout reads into surrounding memory until it encounters a random null byte (or crashes with a read access error).如果没有那个终止符, std::cout会读入周围的内存,直到遇到随机空字节(或因读取访问错误而崩溃)。 That is why you are seeing std::cout output random garbage after your data.这就是为什么您会在数据之后看到std::cout输出随机垃圾。

You are also not following the Rule of 3/5/0 , as you are missing a default constructor, copy and move constructors, and copy and move assignment operators.您也没有遵循3/5/0 规则,因为您缺少默认构造函数、复制和移动构造函数以及复制和移动赋值运算符。

Try this:尝试这个:

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