【问题标题】:Strange behavior (anonymous namespace with swscanf)奇怪的行为(带有 swscanf 的匿名命名空间)
【发布时间】: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


【解决方案1】:

swscanf 格式字符串错误。 %02x 需要一个无符号整数而不是 uint8_t。

试试这个:

    int rc = swscanf(str.c_str(),
        L"%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%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);

【讨论】:

    猜你喜欢
    • 2012-08-26
    • 2020-01-14
    • 1970-01-01
    • 2017-05-10
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    相关资源
    最近更新 更多