【发布时间】:2023-01-13 05:07:37
【问题描述】:
我有下一个实验代码。该代码因标记行上的分段错误而失败。
如果我从匿名命名空间中取出 str2MxfKey 函数或给命名空间命名,代码将毫无问题地运行。
这种奇怪的行为只在发布版本上重现。有人可以向我解释该问题的根本原因吗?
Ubuntu 22.04、cmake 3.22.1、gcc 11.3.0
struct mxfKey
{
uint8_t octet0;
uint8_t octet1;
uint8_t octet2;
uint8_t octet3;
uint8_t octet4;
uint8_t octet5;
uint8_t octet6;
uint8_t octet7;
uint8_t octet8;
uint8_t octet9;
uint8_t octet10;
uint8_t octet11;
uint8_t octet12;
uint8_t octet13;
uint8_t octet14;
uint8_t octet15;
};
namespace {
mxfKey str2MxfKey(const std::wstring &str) {
mxfKey k;
int rc = swscanf(str.c_str(),
L"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", // mxfkey
&k.octet0, &k.octet1, &k.octet2, &k.octet3,
&k.octet4, &k.octet5, &k.octet6, &k.octet7,
&k.octet8, &k.octet9, &k.octet10, &k.octet11,
&k.octet12, &k.octet13, &k.octet14, &k.octet15);
if (rc != 16) {
throw std::runtime_error("Error in str2MxfKey");
}
return k;
}
}
void someExperiments() {
std::wstring wstr = L"8c2197ad00e9476b8213b367123e506e";
std::wcout << "Start" << std::endl;
str2MxfKey(wstr);
std::wcout << wstr << std::endl; // <---- Segmentation fault (core dumped)
std::wcout << "End" << std::endl;
}
int main(int argc, char* argv[]) {
someExperiments();
...
}
【问题讨论】:
-
段错误的原因通常不是段错误发生的地方。此外,更改代码中看似无关的部分会对代码的作用产生影响,这也是未定义行为的一个很好的指示。
-
@AlanBirtles 你应该用 -Wpedantic 或类似的东西编译它。 VS2022 发出此警告来解释问题:rning C4477: 'swscanf': 格式字符串 '%02x' 需要类型为 'unsigned int *' 的参数,但可变参数 16 的类型为 'uint8_t *'
标签: c++ gcc scanf wstring anonymous-namespace