尝试连接两个字符串时崩溃

Crash while trying to concatenate two strings

本文关键字:两个 字符串 崩溃 连接      更新时间:2023-10-16
#include<iostream>
using namespace std;
char *concat(char *string1,char *string2)
{
          char *stringfinal=new char[strlen(string1)+strlen(string2)+2];
          stringfinal=string1;
          char *dest=new char[strlen(string1)+strlen(string2)+2];
          dest = stringfinal;
          while(*dest != '')
          {
                      dest++;
          }
          *dest=' ';  // Point 1

          while(*string2 != '')        
               *dest++=*string2++;  //Point2
          *dest='';
          return stringfinal; 
}
int main()
{
    char *str1="Anurag";
    char *str2="Jain";
    char *strfinal = new char[strlen(str1)+strlen(str2)+2];
    strfinal=concat(str1,str2);
    cout<<strfinal;
    cin.get();
}

你的问题是你似乎认为

stringfinal=string1

dest = stringfinal;

正在执行字符串副本,而它们实际上只是重新签名deststringfile指针指向其他地方(并立即丢失您刚刚新增的内存(。

您可能想要strcpy(stringfile, string1)

即使修复了这个错误,这也不是当今人们编写C++方式的一个非常光辉的例子。 你几乎肯定会更好地使用 std::string,它会为你正确地完成所有这些字符串/指针/分配工作,让你考虑更重要的事情。

但是,如果您只是想了解内置字符串类背后的内容,那么对您来说,更多的功能......

我看到的第一个问题是这里的第二行:

char *stringfinal=new char[strlen(string1)+strlen(string2)+2];
stringfinal=string1; //problematic line

首先分配内存,变量stringfinal保存此内存。然后你用string1持有的内存覆盖这个变量。您新分配的内存消失了,问题从这里开始,第二行。

这里也有类似的错误:

char *dest=new char[strlen(string1)+strlen(string2)+2];
dest = stringfinal;

dest持有的新分配的内存在您用 stringfinal 覆盖它的那一刻消失了。

无论如何,您应该将std::string用作:

std::string string1;
std::string string2;
//...
std::string stringfinal = string1 +"  " + string2;

如果不std::string,则应使用std::strcpystd::strcat而不是手动循环,例如:

char *concat(char *string1,char *string2)
{
    char *stringfinal=new char[strlen(string1)+strlen(string2)+3];
    std::strcpy(stringfinal,string1);                      //^^^ note this!
    std::strcpy(stringfinal, "  ");
    std::strcat(stringfinal,string2);
    return stringfinal;
}

既然你标记了你的问题c++

int main()
{
    const std::string str1("Anurag");
    const std::string str2("Jain");
    const std::string strfinal(str1 + str2);
    std::cout << strfinal;
    return 0;
}
不幸的是,

您的代码有很多问题。我真的不知道从哪里开始。

我只是概述你应该做什么怎么样?

  • 创建一个新的字符数组,其new足够大,以容纳字符串和终止
  • 循环访问string1将每个字符复制到新数组
  • 循环访问string2将每个字符复制到新数组
  • 返回新数组。

但是,由于您使用的是 c++,因此我建议使用实际字符串。你上面有的真的是C和new

编辑:此外,您不会在呼叫之外分配空间,而是将其存储在指针中:

char *strfinal = concat(str1,str2);

首先这是错误的:

stringfinal=string1;

不会做你认为它做的事情,而是使用 strcpy(stringfinal, string1(其次,移动指针不是一个好的编程方法,因为你会失去起点。相反,您可以将其复制到另一个指针并递增副本。您正在尝试做的事情(我假设您想自己连接字符串(可以通过以下方式完成

char* dest = new char[strlen(str1)+strlen(str2)+1];
int i=0;
while(str1[i] != '')
{
    dest[i] = str1[i];
    i++;
}
int j=0;
while(str2[j] != '')
{
    dest[i] = str2[j];
    i++;
    j++;
}
dest[i] = '';
return dest; 
char *stringfinal=new char[strlen(string1)+strlen(string2)+2];
stringfinal=string1;

您从大小为 strlen(string1)+strlen(string2)+2 的免费存储中获取了内存。可能是一个额外的 2,我假设空格和一个终止字符。在下一条语句中,您将stringfinal指向 string1 ,导致内存泄漏。通过前面new语句获得的记忆被放置在没有人可以访问的自由道路上。接下来的陈述也是如此。

char *dest=new char[strlen(string1)+strlen(string2)+2];
dest = stringfinal;

因此,最后dest指向string1指向只读位置所指向的位置。并且您正在尝试使用以下语句修改只读位置 -

*dest = ' '; // Point 1

这就是导致崩溃的原因。


char *str1="Anurag";
char *str2="Jain";

两个str1, str2都指向只读位置,并且您将其作为参数传递给concat函数。此外,每个new都应该与delete/delete[]相关联,在您的情况下,它是delete[] .

伙计,所有这些内存分配都是怎么回事,让我发疯,这是您的工作代码,需要一点点更改:

#include<iostream>
#include<cstring>
using namespace std;
char * concat(char *string1,char *string2,char *stringfinal)
{
          char *p = stringfinal;
          while(*(p++)=*(string1++)); 
          p--;
          *p=' '; 
          p++;
          while(*(p++)=*(string2++));
                    return stringfinal;
}
int main()
{
    char *str1="Anurag";
    char *str2="Jain";
    char *stringfinal=new char[strlen(str1)+strlen(str2)+2];
    stringfinal=concat(str1,str2,stringfinal);
    cout << stringfinal << endl;
}