【问题标题】:How to fix error of appending a literal string to a C string?如何修复将文字字符串附加到 C 字符串的错误?
【发布时间】:2016-01-23 23:37:26
【问题描述】:

我的最后一个功能不起作用。此函数将文字字符串附加到 C 字符串。它检查 C 字符串中是否有足够的空间来附加文字字符串。如果没有足够的空间,则必须将 C 字符串长度扩展为(字面字符串长度 + C 字符串长度)的两倍大小。然后它可以将文字字符串附加到 C 字符串中。在我运行程序并输入文本字符串后,会显示第一个输出语句,然后在我不断收到“在抛出 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());

}

【问题讨论】:

  • 你为什么不用std::string?
  • 你在学习指针吗?因为否则你应该使用std::string
  • 添加一些输出以显示sizeof(s3) 的值。这不是你想的那样。
  • sizeof(s3) 可能返回 1,因为它获取指针的大小。我不确定你会在那条线上实现什么
  • @Pooya - 它几乎肯定不会是 1。那将是一个相当不寻常的架构。也许是一些 DSP,但不是主流计算机。

标签: c++ string function pointers c-strings


【解决方案1】:

问题 1:

您对add() 的实现可能会导致缓冲区溢出:

这是你的主要内容:

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什么都不会发生,仍然指向原来的地方。

要纠正第二个问题,您需要通过引用传递指针。或者更改函数的签名以返回 s3 指针。在这种情况下,你会在 main 中写:s3 = append (s3, ...);

【讨论】:

  • 我需要将 append() 设为 void 函数并且不返回任何内容。为了纠正第二个问题,如果我想通过引用传递指针,我该怎么做?非常感谢您的帮助。
  • @Mark 好的!只需在参数声明中的 s3 之前放一个 &。
  • 会不会是这样的void append(char &amp;s3, string literalStr)?我尝试以这种方式声明它void append(char *&amp;s3, string literalStr),但没有成功。
  • 它应该看起来像第二种形式。它不起作用,因为在您的 if-bloc 中,您将 s3 重新定义为 if bloc 的局部变量(隐藏参数。不要写 char *s3 = new ... 而只是 s3 = new ...Demo
  • 是的!并且为 s3 重新分配内存后,您应该复制旧位置的字符串,并释放不再使用的内存。
猜你喜欢
  • 2021-10-04
  • 2012-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-14
相关资源
最近更新 更多