gpt4 book ai didi

c - strncat 导致缓冲区溢出

转载 作者:行者123 更新时间:2023-12-02 16:16:06 25 4
gpt4 key购买 nike

如何将 strncat 与堆对象一起使用?

我试图编写一个简单的函数来将 2 个字符串连接在一起并返回结果,但是,如果不使返回缓冲区非常大(增加大约 5000 的长度)以使其不会溢出,我就无法运行它。

我可能只是错误地使用了 strncat 函数,使用堆对象而不是固定长度的字符数组。但我不知道如何用其他方式来写它。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *concatStrings(char *arg1, char *arg2) {
char *ret = malloc(strlen(arg1) + strlen(arg2));
strncpy(ret, arg1, strlen(arg1));
strncat(ret, arg2, strlen(arg2));
ret[strlen(arg1)+strlen(arg2)] = '\0';
return ret;
}

int main(int argc, char *argv[]) {
if (argc == 3) {
char *print = concatStrings(argv[1], argv[2]);
printf("\n%s", print);
free(print);
}
return 0;
}

最佳答案

对于初学者来说,函数应该这样声明

char * concatStrings( const char* arg1, const char* arg2 );

因为指针arg1arg2 指向的字符串在函数内没有改变。

在这个内存分配中

char *ret = malloc(strlen(arg1) + strlen(arg2));

您忘记为空终止字符 '\0' 保留内存。你必须写

char *ret = malloc( strlen(arg1) + strlen(arg2) + 1 );

在此调用中使用魔数(Magic Number) 10

strncpy(ret,arg1,10);

没有意义。

如果相反,您将编写示例

strncpy(ret,arg1,strlen(arg1));

然后下一个电话

strncat(ret,arg2,strlen(arg2));

将调用未定义的行为,因为调用 strncpy 没有将空终止字符 '\0' 附加到指针 ret 指向的字符串。

至少只写会好得多

strcpy( ret, arg1 );

在任何情况下,您的函数实现都是低效的。例如,参数 arg2

调用函数 strlen 两次
char *ret = malloc(strlen(arg1) + strlen(arg2));
//...
strncat(ret,arg2,strlen(arg2));

另外 strncat 的调用也是低效的,因为该函数需要遍历整个目标字符串以找到它的终止零。

函数可以这样定义

char * concatStrings( const char* arg1, const char* arg2 )
{
size_t n1 = strlen( arg1 );
char *ret = malloc( n1 + strlen( arg2 ) + 1 );

if ( ret != NULL )
{
strcpy( ret, arg1 );
strcpy( ret + n1, arg2 );
}

return ret;
}

这是一个演示程序。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char * concatStrings( const char* arg1, const char* arg2 )
{
size_t n1 = strlen( arg1 );
char *ret = malloc( n1 + strlen( arg2 ) + 1 );

if ( ret != NULL )
{
strcpy( ret, arg1 );
strcpy( ret + n1, arg2 );
}

return ret;
}

int main(void)
{
const char *argv1 = "Hello ";
const char *argv2 = "World!";

char *print = concatStrings( argv1, argv2 );

if ( print != NULL ) puts( print );

free( print );

return 0;
}

程序输出为

Hello World!

在函数中用 memcpy 替换 strcpy 的第一次调用会更好。那就是函数也可以长这样

char * concatStrings( const char* arg1, const char* arg2 )
{
size_t n1 = strlen( arg1 );
char *ret = malloc( n1 + strlen( arg2 ) + 1 );

if ( ret != NULL )
{
memcpy( ret, arg1, n1 );
strcpy( ret + n1, arg2 );
}

return ret;
}

关于c - strncat 导致缓冲区溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66688740/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com