我有一个语句
strncpy(&data->m_bin->data,versionStr,data->m_bin->sizeData);
在我的应用程序中,它本身很好并且运行良好。这里data-> m_bin->数据是一个char,其中调用应用程序确保其后面是一个数据库,该数据已足够大,可以将所有数据保留为strncpy()。
但是,当我使用GCC/Linux构建此功能时,此功能会在__strncpy_chk()中崩溃。因此,看来我的strncpy()使用错误的长度S1替换为__strncpy_chk()。
那么,我如何确保__ strncpy_chk()的调用,以s1的正确长度?
谢谢!
在此处data-> m_bin->数据是一个char,其中调用应用程序可确保其后面的数据库,该数据已足够大,可以将所有数据保留为strncpy()。
这导致有效的C程序是不寻常的。指针出处规则通常暗示这会导致不确定的行为。
如果char
在结构的末端,则可以使用灵活的数组成员,以使编译器的意图更清晰。
如果您不想更改源,则可以使用-U_FORTIFY_SOURCE
或-D_FORTIFY_SOURCE=0
编译。这将禁用用强化版本替换strncpy
。
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);
如何确保
的正确长度__strncpy_chk()
的速度为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] = ' ';
您可能应该使用-Wall
打开警告。我怀疑您应该使用address of
运算符。