当printf std :: string不正确时,内存和cpu下发生了什么?

时间:2016-03-25 13:35:23

标签: c++ string printf

我们知道,printf函数只能打印像int,char,char *等POD类型。如果我们传递std::string类型而不调用它的c_str()成员函数,然后通过提出ILLEGAL INSTRUCTION信号来中止该程序。

就像下面的简单代码一样。

#include <iostream>
#include <string>
int main()
{
    std::string str("hello world");
    printf("%s\n", str);
    return 0;
}

如果使用g++ -g构建它,并设置ulimit -c unlimited,则在运行程序时,它将在运行时进行核心转储。如果你在核心文件上运行gdb,gdb会告诉你这个程序在行std::string str("hello world");出错了,非常奇怪。 这是截图。 Running program Gdb debugging 所以我正在考虑这种现象下的机制。

  1. printf如何举起非法指令?像std :: string内存组成,cpu非法指令等......
  2. 为什么代码上面的gdb声明出错而不是printf行?
  3. 我知道这可能是一个微不足道的问题,但了解它的机制非常酷。

2 个答案:

答案 0 :(得分:2)

printf的参数的格式字符串包含%s并且相应的参数不是char指向\0的指针时,程序的行为为{{1 }}

通常undefined将包含一些包含实际数据信息的指针(开始指针,结束指针/大小等),并且数据可能会或可能不会以空值终止。因此,尝试使用std::string函数打印std::string是一种未定义的行为。 (请注意:C的类型为std::string::c_str且空终止,因此可以使用const char *打印

printf无法在编译时检查参数的有效性,并且它会消耗参数。如果它读取的数据不可读,则可能会实现陷阱实现,或者它可能会崩溃或可能按预期工作。

答案 1 :(得分:1)

C ++ 03标准表示,将不是POD的东西传递给varargs(...)参数是未定义的行为。事实上,gcc会向你发出一个警告,告知程序会崩溃(但无论如何都会成功编译)。

具体来说,这意味着

printf("This doesn't use the arguments", std::string(""));

可能会崩溃。

顺便提一下,在C ++ 11中,这有条件地支持使用实现定义的语义定义的实现,但仍然最好避免&#39;。

没有机制,也没有任何特定行为的保证。它可能崩溃,它可以工作,它可以重新格式化您的硬盘驱动器。看看特定的编译器在做什么真的没什么兴趣。