首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >strncpy被__strncpy_chk替换,并失败。

strncpy被__strncpy_chk替换,并失败。
EN

Stack Overflow用户
提问于 2019-03-12 06:55:56
回答 2查看 289关注 0票数 1

我有一份声明

代码语言:javascript
运行
复制
strncpy(&data->m_bin->data,versionStr,data->m_bin->sizeData);

在我的应用程序中,它本身很好并且运行良好。在这里,data->m_bin->data是一个char,其中调用应用程序确保它后面跟着一个数据库,该数据库足够大,足以保存由strncpy()提交的所有数据。

但是,当我使用GCC/Linux将其构建为发行版时,这个函数会在__strncpy_chk()中崩溃。因此,我的strncpy()似乎被__strncpy_chk()替换,参数s1使用了错误的长度。

那么,如何确保用正确的s1长度调用s1()?

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-12 07:33:19

strncpy(&data->m_bin->data,versionStr,data->m_bin->sizeData);

address of接线员在我看来很可疑。我希望这样的事情:

代码语言:javascript
运行
复制
strncpy(data->m_bin->data,versionStr,data->m_bin->sizeData);

或者也许:

代码语言:javascript
运行
复制
strncpy(&data->m_bin->data[0],versionStr,data->m_bin->sizeData);

如何确保用正确的s1长度调用s1?

好吧,你本身不可能。这是FORTIFY_SOURCE和对象大小检查的一部分,编译器可以推断出目标缓冲区大小。

假设data是一个大小为sizeData的数组,您可以执行如下操作。

代码语言:javascript
运行
复制
/* avoid undefined behavior */
ASSERT(data->m_bin->data != NULL);
ASSERT(versionStr != NULL);
ASSERT(data->m_bin->sizeData > 0);

size_t l1 = data->m_bin->sizeData;
size_t l2 = strlen(versionStr);

/* min function */
size_t len = l1 < l2 ? l1 : l2;

/* if versionStr is shorter than len, then data will be backfilled */
strncpy(data->m_bin->data, versionStr, len);

/* NULL terminate, even if it truncates */
data->m_bin->data[data->m_bin->sizeData-1] = '\0';

您可能应该使用-Wall打开警告。我想你应该因为使用address of操作符而得到一个。

票数 1
EN

Stack Overflow用户

发布于 2019-03-12 07:45:14

在这里,data->m_bin->data是一个char,其中调用应用程序确保它后面跟着一个数据库,该数据库足够大,足以保存由strncpy()提交的所有数据。

不寻常的是,这会导致一个有效的C程序。指针出处规则通常意味着这会导致未定义的行为。

如果char位于结构的末尾,则可以使用灵活的数组成员,以使编译器更清楚地了解其意图。

如果不想更改源代码,可以使用-U_FORTIFY_SOURCE-D_FORTIFY_SOURCE=0进行编译。这将禁用用强化版本替换strncpy

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55115709

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档