【发布时间】:2020-02-17 21:45:46
【问题描述】:
我不是 C 开发人员,我可能会出错(我正在对旧代码进行更改):
有一个名为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[](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 尚未构建)。
编辑:为了清楚起见,line 和message 的修改发生在我通过line[N] = 0; 的一步的同时发生
删除了 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。对我来说,这很有趣。
【问题讨论】:
-
[Tangent] 如果您使用 C++,为什么不使用
std::string来管理您的字符串对象。它使这样的代码不再需要。 -
@gorZ 提供一个演示问题的最小完整程序
-
strncpySafe正在将count-1字符从源复制到目标。line[message_offset_2] = 0;正在向目标添加终止,但不需要,如果您更新 strncpy 以复制直到 count 或传递 offset+1(取决于计数器的使用方式) -
你是说
line的字符被修改了,message的字符也被修改了——通过samestrncpySafe调用?这听起来像是您传入了一个伪造的message缓冲区,该缓冲区在调用堆栈(欠载)上有别名。或者可能 message_offset_2 大于 1024。可以assert这样的事情。 -
@IgorZ 字符串是否重叠?
标签: c++ undefined-behavior c-strings strncpy