C++ strncpy之后字符数组的错误行为

C++ strncpy之后字符数组的错误行为,c++,undefined-behavior,c-strings,strncpy,C++,Undefined Behavior,C Strings,Strncpy,我不是C-dev,我可能会出错,因为我正在对旧代码进行更改: 有一个名为strncpySafe的函数,我可以看到它只是strncpy上的一个包装器: void strncpySafe(char *strDest, const char *strSource, int count) { strncpy(strDest, strSource, count-1); strDest[count-1] = '\0'; } 步骤本身,其中是从源a到源B的偏移量的副本: void Fo

我不是C-dev,我可能会出错,因为我正在对旧代码进行更改:

有一个名为strncpySafe的函数,我可以看到它只是strncpy上的一个包装器:

void    strncpySafe(char *strDest, const char *strSource, int count)
{
    strncpy(strDest, strSource, count-1);
    strDest[count-1] = '\0';
}
步骤本身,其中是从源a到源B的偏移量的副本:

void Foo(const char *message) {
char line[1024];
...
strncpySafe(line, &message[message_offset], count);
在最后一步中,他们正在修改复制的行[],消息[]应保持不变:

line[N] = 0;
在最后一步中,我可以从VSCode调试器中看到第[N]行正在更改,同时消息[N]也在修改。 我使用的是Ubuntu/g++-8,-march=x86-64,-std=c++11。 是关于相同的指针吗?这是不是strncpy的错误用法? 多谢各位

ps:在windows和linux的游戏客户端中使用了相同的代码,我可以说,在windows上它没有被复制windows是在旧的c编译器上构建的,还没有使用相同的c++11构建进行检查

编辑:为了清楚起见,当我通过一个步骤时,行[N]=0,行和消息的修改同时发生

已删除消息\u偏移量\u 2的错误命名。这是一个计数。 让我提供一个执行示例:

strncpySafe(line, &message[5], 10); // It copies 10 elements from 5th
line[5] = 0; // this leads that message[5] also gets 0 for it's element
边界偏移和计数器似乎没有错误


我同意这段代码已被弃用,逻辑可能不清楚为什么要这样做,我可以使用std::string。对我来说,这很有趣,为什么会发生这种情况。

考虑到您在问题中所写的数组消息也发生了更改,那么很明显,您使用的函数不正确,因此您有未定义的行为

例如,命名为message_offset_2的第三个参数指定应从字符串复制到目标字符数组的字符数。因此,它不应该被命名为message_offset_2

未定义行为的另一个原因可能是使用重叠数组

因此,要么第三个参数指定错误,要么字符数组发生重叠

但无论如何,函数的声明和定义都很糟糕

如果它是标准C函数strncpy的包装器,那么它至少应该声明为

char * strncpySafe( char * restrict s1, const char * restrict s2, size_t n );
或者如果它被声明为C++函数,则

char * strncpySafe( char * s1, const char * s2, size_t n );
如果函数设计为复制n个字符,那么函数体应该如下所示

if ( n )
{
    strncpy( s1, s2, n );
    s1[n] = '\0';
}

return s1;
因此,目标阵列应至少具有n+1个元素

以及C标准,7.23.2.4 strncpy函数

如果复制发生在重叠的对象之间,则行为为 未定义


[切线]如果使用C++,为什么不使用STD::string来管理字符串对象。它使这样的代码不需要输入。@gorZ提供了一个最小的完整程序来演示问题strncpysafe正在将count-1字符从源复制到目标。行[message_offset_2]=0;如果您根据计数器的使用方式将strncpy更新为copy till count或pass offset+1(取决于计数器的使用方式),是否将终止添加到目的地(但不需要)?您是否说行的字符被修改,消息的字符也被修改?通过相同的strncpySafe调用?这听起来像是您传入了一个伪造的消息缓冲区,该缓冲区在调用堆栈的运行中使用了别名。或者消息_offset_2可能大于1024。人们可以断言这样的事情。@IgorZ字符串是否重叠?