C++ C++;字符数组连接

C++ C++;字符数组连接,c++,string,char,assertion,strcat,C++,String,Char,Assertion,Strcat,我试图重载加号来连接两个字符串,但是我一直得到一个错误 VS 2010给出了一条断言失败的消息:“表达式:(L“缓冲区太小”&&0)文件:f:\dd\vctools\crt\u bld\self\u x86\crt\src\tcscat\u s.inl行:42 你认为我的代码有什么问题 #include "stdafx.h" class MyString{ int l; // the length of the array pointed by buf char *buf;

我试图重载加号来连接两个字符串,但是我一直得到一个错误

VS 2010给出了一条断言失败的消息:“表达式:(L“缓冲区太小”&&0)文件:f:\dd\vctools\crt\u bld\self\u x86\crt\src\tcscat\u s.inl行:42

你认为我的代码有什么问题

#include "stdafx.h"

class MyString{
    int l;  // the length of the array pointed by buf
    char *buf; //pointer to a char array
public:
        ...
    MyString(char *);
    friend MyString operator+(MyString &,MyString &);
        ...
};

MyString::MyString(char *p)
{
    buf=new char[strlen(p)+1];
    strcpy_s(buf,strlen(p)+1,p);
    l=strlen(p)+1;
}

MyString operator+(const MyString &a,const MyString &b)
{
    MyString result("");
    result.l=a.l+b.l;
    delete[] result.buf;
    result.buf=new char[result.l+1];
    result.buf[0]='\0';
    strcat_s(result.buf,result.l+1,a.buf);
    strcat_s(result.buf,result.l+1,b.buf);
    return result;
}

int _tmain(int argc, _TCHAR* argv[])
{
    MyString a("hello"),b("world"),c("");
    c=a+b;
    system("pause");
    return 0;
}

现在可以了!谢谢大家

应该是
result.buf=newchar[result.l+1]
允许空字符。

它应该是
result.buf=新字符[result.l+1]
允许空字符。

在运算符+中,变量“MyString result”在堆栈上声明,随后通过引用返回,这是错误的

然后编辑了这篇文章。变量“result”不再在堆栈上声明,而是在堆上分配。然而,随后出现了内存泄漏

这里正确的做法是按值返回,并在堆栈上声明“MyString result”。还要确保您有一个复制构造函数。还有一个破坏者

您还应该使构造函数在运算符+中使用“const char*”

变量“MyString result”在堆栈上声明,随后通过引用返回,这是错误的

然后编辑了这篇文章。变量“result”不再在堆栈上声明,而是在堆上分配。然而,随后出现了内存泄漏

这里正确的做法是按值返回,并在堆栈上声明“MyString result”。还要确保您有一个复制构造函数。还有一个破坏者

您还应该使构造函数接受“const char*”

strcat_s
的第二个参数是目标缓冲区的大小,而不是应附加的字符串的大小。 所以你需要把它改成

strcat_s(result->buf,result->l+1,a.buf);
strcat_s(result->buf,result->l+1,b.buf);
operator+实现的其余部分也被破坏,其他人已经注意到了这一点。新建一个实例,然后按值返回它是毫无意义的。只需在堆栈上实例化结果并按值返回即可

strcat_s
的第二个参数是目标缓冲区的大小,而不是应附加的字符串的大小。 所以你需要把它改成

strcat_s(result->buf,result->l+1,a.buf);
strcat_s(result->buf,result->l+1,b.buf);

operator+实现的其余部分也被破坏,其他人已经注意到了这一点。新建一个实例,然后按值返回它是毫无意义的。只需在堆栈上实例化结果并按值返回。

这将给出相同的断言失败消息;我认为a.buf结尾的“\0”被b.buf中的第一个字符替换,它给出了相同的断言失败消息;我以为a.buf结尾的“\0”已被b.bufw中的第一个字符替换。为什么要将result.buf中的第一个字符设置为空字符?strcat可能认为这是缓冲区的结尾。因为strcat在字符串的结尾处连接到它找到的“\0”。此问题已编辑,以便包括接受答案提出的修复。这使得答案有点毫无意义。这对未来的读者有什么用处呢?问题还包括以前版本的代码。。。点击“8小时前编辑”。现在它工作了,让我建议一个优化。版本1:添加一个(可能是私有的)接受两个字符串并将它们连接起来的构造函数,然后在操作符+(有效地将连接代码移动到构造函数)中使用该构造函数。版本2:添加一个不初始化对象的(私有)构造函数,并在运算符+(将串联代码保留在运算符+)中使用它。-这样你就可以安全地进行一次新的、一次删除和一次对strcpy_的调用。同时移动
l=strlen(p)+1
在其他两次调用之前先调用
char*
ctor,然后在接下来的两行中使用
l
而不是
strlen
。为什么要将result.buf中的第一个char设置为空字符?strcat可能认为这是缓冲区的结尾。因为strcat在字符串的结尾处连接到它找到的“\0”。此问题已编辑,以便包括接受答案提出的修复。这使得答案有点毫无意义。这对未来的读者有什么用处呢?问题还包括以前版本的代码。。。点击“8小时前编辑”。现在它工作了,让我建议一个优化。版本1:添加一个(可能是私有的)接受两个字符串并将它们连接起来的构造函数,然后在操作符+(有效地将连接代码移动到构造函数)中使用该构造函数。版本2:添加一个不初始化对象的(私有)构造函数,并在运算符+(将串联代码保留在运算符+)中使用它。-这样你就可以安全地进行一次新的、一次删除和一次对strcpy_的调用。同时移动
l=strlen(p)+1在其他两次调用之前先调用
char*
ctor,然后在接下来的两行中使用
l
而不是
strlen
。你所说的非常有趣,这就是我要做的,但是你知道
strcat_(result->buf,strlen(a.buf),a.buf)有什么问题吗?你说的很有趣,我也会这么做,但是你知道strcat_s(result->buf,strlen(a.buf),a.buf)有什么问题吗