【问题标题】:Does strcat_s() require the use of realloc()?strcat_s() 是否需要使用 realloc()?
【发布时间】:2017-07-29 07:07:29
【问题描述】:

以示例代码为例*:

char *string = (char*)malloc(sizeof(char));
strcat_s(string, strlen(string) + 10 + 1, "characters");

上面的代码编译并运行,让我相信内存重新分配正在发生。但是,当以更大的规模应用时(也以递归方式),我会在随机位置收到内存错误(每次运行程序时都不同)。

strcat_s() 会超出边界吗?因此需要 realloc() 来确保正确分配内存吗?

注意:这些错误可能是无关的,尽管它们是在应用示例中的代码后偶然出现的。

*我最初只分配一个字节的原因是,在上下文中我使用的是动态大小,所以string 的大小会改变,但幅度未知。

【问题讨论】:

  • 检查reference如果目标数组对于 src 和 dest 的内容以及终止空字符都不够大,则行为未定义。
  • 我不建议在 C++ 中使用 mallocstrlenstrcat_s。有更好的工具。
  • @FredLarson 非常好——我考虑过使用 std::string,但感觉有点像作弊。但考虑到大规模手动内存管理的艰巨性,我想我可能不得不这样做。
  • 在工作中使用正确的工具并不是作弊。
  • "让我相信内存重新分配正在发生" - 没有一个标准的 str*** 函数分配内存。

标签: c memory realloc strcat-s


【解决方案1】:

在这里你正好分配了 1 个字符

 char *string = (char*)malloc(sizeof(char));

所以string 可以保存的唯一字符串是""(零长度字符串)

然后您尝试将字符串"characters" 附加到string,它不能包含除"" 之外的字符串并且未初始化。此外,strlen(string) 的结果将是不确定的,因为 string 没有初始化。

 strcat_s(string, strlen(string) + 10 + 1, "characters");

你可能想要这个:

char *string = (char*)malloc(sizeof(char) * 100);   // allocate 100 bytes
strcpy(string, "Hello ");
strcat_s(string, 100, "characters");

printf("%s\n", string);  // will display "Hello characters".

【讨论】:

  • 我总是想指出 sizeof(char) 在定义上是 1,所以你也可以使用 malloc(100)
  • @FredLarson 完全正确,但如果我写了malloc(100),其他人肯定会评论我宁愿写sizeof(char) * 100 来强调我们正在分配字符
  • 我会成为其中之一 :) 更喜欢 sizeof(char) * 100 而不是 100。其实我更喜欢calloc(100, sizeof(char))
【解决方案2】:

上面的代码编译运行,让我相信内存 正在重新分配。

仅仅因为程序看起来像你期望的那样运行并不意味着它是正确的,甚至它的行为完全是从 C 的角度定义的。

但是,在更大规模应用时 (也递归),我在随机位置收到内存错误 (每次运行程序都不同)。

strcat_s() 会不会超出界限?

是的。

因此是realloc() 需要确保正确分配内存?

没有。

strcat_s()strcat() 都不执行任何重新分配。他们没有被指定这样做,这样做对他们来说是不安全的。

您收到错误是因为您错误地使用了该功能(即使您没有收到错误)。您有责任确保第二个参数不超过第一个参数指向的数组的大小,但您公然无视该责任。我想你只是对strcat_s() 应该做什么以及它的第二个参数的含义有一个严重的误解。

strcat_s() 提供但strcat() 没有提供的主要功能是检查指定的 数组边界是否由于第二个字符串的长度超过了可以容纳的范围而超出。这使您无需在执行连接之前检查第二个字符串的长度,这是有利的,因为strcat_s() 可以以非常低的成本自行完成,因为它无论如何都必须扫描该字符串。 strcat_s() 没有比任何其他 C 操作或函数更多的能力来独立确定第一个参数指向的数组有多长。它依赖于你来告诉它。

如果您需要适应数组大小的动态调整,那么这是您的责任,就像跟踪分配的当前大小一样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-17
    • 2011-08-30
    • 2014-02-08
    • 2012-02-22
    • 2014-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多