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