【问题标题】:printf format string: order of arguments and Segmentation Faultprintf 格式字符串:参数顺序和分段错误
【发布时间】:2014-05-03 04:43:59
【问题描述】:

如果我更改 printf 格式字符串中的参数顺序,我会遇到分段错误。

int main( int argc, char *argv[] )
{
    _uint64 test_var = 50000000;
    char str[20] = { };
    sprintf( str, "TEST_STRING" );

    printf( "test_var %lld str %s\n", test_var, str ); //OK
    printf( "str %s test_var %d\n", str, test_var ); //OK
    printf( "test_var %d str %s\n", test_var, str ); //Segmentation Fault

    return EXIT_SUCCESS;
}

为什么会出现这个错误?

【问题讨论】:

    标签: c segmentation-fault printf


    【解决方案1】:

    64 位值是 64 位(8 个字节)。 int(这是格式说明符 "%d" 使用的)是 32 位(4 字节)。

    所以printf 在崩溃行中所做的是读取 4 个字节以打印为整数,然后它将读取剩余的四个字节(在 32 位系统上)或剩余的四个字节和前四个字节用作字符串指针的字符串指针(在 64 位系统上)。如您所知,该字符串指针不是有效指针,因此您有 未定义的行为,这在您的情况下会导致崩溃。

    【讨论】:

    • 实际上,对于大多数 64 位代码,它会静默工作。在调用中使用之前,32 位整数将扩展为 64 位。显然,在大多数其他系统上,UB 没有被屏蔽。
    • _uint64 test_var1 = 0xaaaabbbbccccdddd; _uint32 test_var2 = 0x30; printf("结果:test_var1=0x%x test_var2=0x%x test_var2=0x%x\n", test_var1, test_var2, test_var2);结果:test_var1=0xccccdddd test_var2=0xaaaabbbb test_var2=0x30
    【解决方案2】:
    printf( "test_var %d str %s\n", test_var, str ); //Segmentation Fault
                      ^^
    

    你应该使用%lld

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-21
      • 2017-09-28
      • 1970-01-01
      相关资源
      最近更新 更多