1

以示例代码*为例:

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

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

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

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

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

4

2 回答 2

2

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

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

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

strcat_s()不会越界?

是的。

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

不。

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

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

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

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

于 2017-03-08T16:36:29.567 回答
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".
于 2017-03-08T16:09:47.323 回答