我不是C-dev,我可能会出错(我正在对旧代码进行更改(:
有一个叫做strncpySafe
的函数(正如我所看到的,它只是strncpy
上的一个包装器(:
void strncpySafe(char *strDest, const char *strSource, int count)
{
strncpy(strDest, strSource, count-1);
strDest[count-1] = ' ';
}
步骤本身,其中是从源a到源B的拷贝,带有偏移:
void Foo(const char *message) {
char line[1024];
...
strncpySafe(line, &message[message_offset], count);
在最后一步中,他们正在修改复制的line[]
(message[]
应保持不变(:
line[N] = 0;
在最后一步中,我可以从VSCode调试器中看到line[N]
正在更改,同时message[N]
也在修改
我正在使用Ubuntu /g++-8, -march=x86-64, -std=c++11
是关于相同的指针吗?这是strncpy的错误用法吗
谢谢。
ps:同样的代码在windows和linux的游戏客户端中使用,我可以说在windows上它没有被复制(windows是在一个旧的c编译器上构建的,还没有使用相同的c++11版本进行检查(。
EDIT:为了清楚起见,当我使用line[N] = 0;
通过一个步骤时,line
和message
的修改同时发生
删除了message_offset_2
的错误命名。它是count
让我提供一个执行示例:
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] = ' ';
}
return s1;
因此,目的地阵列应至少具有n + 1
元素。
和(C标准,7.23.2.4 strncpy函数(
如果复制发生在重叠的对象之间,则行为为未定义。