[英]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.