如何修复将文字字符串附加到 C 字符串的错误?
How to fix error of appending a literal string to a C string?
我的最后一个功能不起作用。此函数将文字字符串附加到 C 字符串。它检查 C 字符串中是否有足够的 space 来将文字字符串附加到它上面。如果不够space,则必须将C 字符串长度扩展到(文字字符串长度+ C 字符串长度)的两倍。然后它可以将文字字符串附加到 C 字符串。在我 运行 程序并输入文本字符串后,显示第一个输出语句,然后在我不断收到 "terminate called after throwing an instance of std::bad_alloc" 错误并且程序停止工作之后。所有其他功能在此追加功能之前工作。有没有办法修复最后一个附加函数的工作?
int main()
{
char* s1 = assign();
char* s2 = assign(" C++ ");
char* s3 = add(s1, s2);
cout << "length of \"" << s3 << "\" is " << strlen(s3) << endl;
append(s3, "programming language"); // This function doesn't work
cout << "length of \"" << s3 << "\" is " << strlen(s3) << endl;
return 0;
}
char* assign()
{
const int SIZE = 100;
char temp[SIZE];
int length;
int twicelen;
cout << "Enter a text string which will be used to append literal strings to it: ";
cin.getline(temp, SIZE);
length = strlen(temp);
twicelen = length * 2;
char* newCstring = new char[twicelen];
strcpy(newCstring, temp);
return newCstring;
}
char* assign(string str)
{
int len = strlen(str.c_str());
int newlen = len * 2;
char* newStr = new char[newlen];
strcpy(newStr, str.c_str());;
return newStr;
}
char* add(char* s1, char* s2)
{
strcat(s1, s2);
return s1;
}
void append(char* s3, string literalStr) // Every function before this works and this is where the program gives an error and closes.
{
if (sizeof(s3) < (strlen(s3) + strlen(literalStr.c_str()) + 1))
{
int expandLength = (strlen(s3) + strlen(literalStr.c_str())) * 2;
char* s3 = new char[expandLength];
strcat(s3, literalStr.c_str());
}
else
strcat(s3, literalStr.c_str());
}
问题 1:
您对 add()
的实施可能会导致缓冲区溢出:
这是您在 main 中的内容:
char* s1 = assign(); // here memory is allocated for the string you input
char* s2 = assign(" C++ "); // here memory is allocated again
char* s3 = add(s1, s2); // <==== ouch
不幸的是,add()
只是创建了一个 strcat() 并没有确保目标字符串有足够的内存。从此,你就进入了恐怖的UB世界。任何事情都可能发生。例如,字符串的结尾 null 可能会丢失,导致 strlen()
找到一个巨大的长度,并在您尝试分配两次如此巨大的数字时导致错误的内存异常。
问题 2:
您的 append()
函数本身存在缺陷。
首先,sizeof(s3)
是指针s3的大小,所以是一个很小的数字。它不是分配字节的大小。因此,您很有可能会进入 if
块(但出于错误的原因)。
接下来,您分配一个新的 s3
。问题是您存储在函数 s3
中的值是函数的本地值。 main中的指针s3
不会有任何变化,仍然指向原来的地方。
要更正第二个问题,您需要通过引用传递指针。或者将函数的签名更改为 return s3
指针。在这种情况下,您将在 main 中写入:s3 = append (s3, ...);
我的最后一个功能不起作用。此函数将文字字符串附加到 C 字符串。它检查 C 字符串中是否有足够的 space 来将文字字符串附加到它上面。如果不够space,则必须将C 字符串长度扩展到(文字字符串长度+ C 字符串长度)的两倍。然后它可以将文字字符串附加到 C 字符串。在我 运行 程序并输入文本字符串后,显示第一个输出语句,然后在我不断收到 "terminate called after throwing an instance of std::bad_alloc" 错误并且程序停止工作之后。所有其他功能在此追加功能之前工作。有没有办法修复最后一个附加函数的工作?
int main()
{
char* s1 = assign();
char* s2 = assign(" C++ ");
char* s3 = add(s1, s2);
cout << "length of \"" << s3 << "\" is " << strlen(s3) << endl;
append(s3, "programming language"); // This function doesn't work
cout << "length of \"" << s3 << "\" is " << strlen(s3) << endl;
return 0;
}
char* assign()
{
const int SIZE = 100;
char temp[SIZE];
int length;
int twicelen;
cout << "Enter a text string which will be used to append literal strings to it: ";
cin.getline(temp, SIZE);
length = strlen(temp);
twicelen = length * 2;
char* newCstring = new char[twicelen];
strcpy(newCstring, temp);
return newCstring;
}
char* assign(string str)
{
int len = strlen(str.c_str());
int newlen = len * 2;
char* newStr = new char[newlen];
strcpy(newStr, str.c_str());;
return newStr;
}
char* add(char* s1, char* s2)
{
strcat(s1, s2);
return s1;
}
void append(char* s3, string literalStr) // Every function before this works and this is where the program gives an error and closes.
{
if (sizeof(s3) < (strlen(s3) + strlen(literalStr.c_str()) + 1))
{
int expandLength = (strlen(s3) + strlen(literalStr.c_str())) * 2;
char* s3 = new char[expandLength];
strcat(s3, literalStr.c_str());
}
else
strcat(s3, literalStr.c_str());
}
问题 1:
您对 add()
的实施可能会导致缓冲区溢出:
这是您在 main 中的内容:
char* s1 = assign(); // here memory is allocated for the string you input
char* s2 = assign(" C++ "); // here memory is allocated again
char* s3 = add(s1, s2); // <==== ouch
不幸的是,add()
只是创建了一个 strcat() 并没有确保目标字符串有足够的内存。从此,你就进入了恐怖的UB世界。任何事情都可能发生。例如,字符串的结尾 null 可能会丢失,导致 strlen()
找到一个巨大的长度,并在您尝试分配两次如此巨大的数字时导致错误的内存异常。
问题 2:
您的 append()
函数本身存在缺陷。
首先,sizeof(s3)
是指针s3的大小,所以是一个很小的数字。它不是分配字节的大小。因此,您很有可能会进入 if
块(但出于错误的原因)。
接下来,您分配一个新的 s3
。问题是您存储在函数 s3
中的值是函数的本地值。 main中的指针s3
不会有任何变化,仍然指向原来的地方。
要更正第二个问题,您需要通过引用传递指针。或者将函数的签名更改为 return s3
指针。在这种情况下,您将在 main 中写入:s3 = append (s3, ...);