我遇到“缓冲区溢出数组索引超出范围”错误

时间:2019-07-17 17:26:05

标签: c c-strings strcpy strcat strncpy

我确实理解该错误,但是不知道什么是正确的解决方案。它说

  

大小为512的数组“文件名”可以使用索引值MIN..1022

是因为strncat之后才调用strncpy吗?

我尝试做strlen,但这引入了其他一些错误。

#define MAX_SIZE 512
void some_function(const char *path)        /*path is also char  
                                             array of size 512*/  
{

    char filename[MAX_SIZE]="";
    char *attr = "/funct";

    strncpy(filename, path, sizeof(filename));
    strncat(filename, attr, sizeof(filename));  //error line

}

对此是否有适当的解决方案。

2 个答案:

答案 0 :(得分:0)

如果使用函数strncpy,则必须将其最后一个字符设置为零字符'\ 0'。否则,您不能保证字符数组包含字符串。

以这种方式使用strncat

strncat(filename, attr, sizeof(filename));

没有道理。数组filename的空间不足,无法容纳字符串attr。但是您正在尝试将sizeof(filename)个字符复制到已经可以完全填充的数组中。

您必须“手动”检查目标数组是否包含足够的空间,以将新字符串追加到已存储的字符串中。

因此没有意义使用函数strncat,因为在任何情况下结果路径都将无效。

您可以使用下面的演示程序中显示的以下方法。

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

#define MAX_SIZE 512

void some_function(const char *path )
{
    char filename[MAX_SIZE] = "";
    const char *attr = "/funct";
    size_t n = strlen( attr );

    strncpy( filename, path, sizeof (filename ) );

    filename[ MAX_SIZE - 1] = '\0';

    if ( n < MAX_SIZE - strlen( filename ) )
    {
        strcat( filename, attr ); 
    }

    puts( filename );
}

int main(void) 
{
    const char *path = "/path";

    some_function( path );

    return 0;
}

或者您可以在函数的开头检查数组是否可以包含两个字符串。例如

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

#define MAX_SIZE 512

void some_function(const char *path )
{
    char filename[MAX_SIZE] = "";
    const char *attr = "/funct";
    size_t n1 = strlen( path );
    size_t n2 = strlen( attr );

    if ( n1 + n2 < MAX_SIZE )
    {
        strcpy( filename, path );

        strcpy( filename + n1, attr ); 
    }

    puts( filename );
}

int main(void) 
{
    const char *path = "/path";

    some_function( path );

    return 0;
}

答案 1 :(得分:0)

编译器的错误消息可能是因为您最多复制511个字节(加上null),然后再串联另一个最大511个字节(加上null),总共1022个字节(加上一个null)。

但是,编译器发现目标只有512个字节并发出警告。

解决方案在注释和其他解决方案中给出,在此不再赘述。