我有一份声明
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()?
谢谢!
发布于 2019-03-12 07:33:19
strncpy(&data->m_bin->data,versionStr,data->m_bin->sizeData);
address of
接线员在我看来很可疑。我希望这样的事情:
strncpy(data->m_bin->data,versionStr,data->m_bin->sizeData);
或者也许:
strncpy(&data->m_bin->data[0],versionStr,data->m_bin->sizeData);
如何确保用正确的s1长度调用s1?
好吧,你本身不可能。这是FORTIFY_SOURCE
和对象大小检查的一部分,编译器可以推断出目标缓冲区大小。
假设data
是一个大小为sizeData
的数组,您可以执行如下操作。
/* 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
操作符而得到一个。
发布于 2019-03-12 07:45:14
在这里,data->m_bin->data是一个char,其中调用应用程序确保它后面跟着一个数据库,该数据库足够大,足以保存由strncpy()提交的所有数据。
不寻常的是,这会导致一个有效的C程序。指针出处规则通常意味着这会导致未定义的行为。
如果char
位于结构的末尾,则可以使用灵活的数组成员,以使编译器更清楚地了解其意图。
如果不想更改源代码,可以使用-U_FORTIFY_SOURCE
或-D_FORTIFY_SOURCE=0
进行编译。这将禁用用强化版本替换strncpy
。
https://stackoverflow.com/questions/55115709
复制相似问题