Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当不正确地打印std::string时,引擎盖下的内存和cpu中发生了什么?_C++_String_Printf - Fatal编程技术网

C++ 当不正确地打印std::string时,引擎盖下的内存和cpu中发生了什么?

C++ 当不正确地打印std::string时,引擎盖下的内存和cpu中发生了什么?,c++,string,printf,C++,String,Printf,我们知道,printf函数只能打印int、char、char*等POD类型,如果我们传递std::string类型而不调用其c_str()成员函数,那么程序将通过发出非法指令信号而中止 就像下面的简单代码一样 #include <iostream> #include <string> int main() { std::string str("hello world"); printf("%s\n", str); return 0; } #包括

我们知道,
printf
函数只能打印int、char、char*等POD类型,如果我们传递
std::string
类型而不调用其
c_str()
成员函数,那么程序将通过发出
非法指令
信号而中止

就像下面的简单代码一样

#include <iostream>
#include <string>
int main()
{
    std::string str("hello world");
    printf("%s\n", str);
    return 0;
}
#包括
#包括
int main()
{
std::string str(“hello world”);
printf(“%s\n”,str);
返回0;
}
如果您使用
g++-g
构建它,并设置
ulimit-c unlimited
,当您运行程序时,它将在运行时转储内核。如果在核心文件上运行gdb,gdb会告诉您该程序在第
std::string str(“hello world”)行出错,很奇怪。
这是截图。
因此,我正在考虑这种现象下的机制

  • printf如何引发非法指令?像std::字符串内存组合、cpu非法指令等
  • 为什么gdb在代码的上一行声明出错,而不是在printf行

  • 我知道这可能是一个很小的问题,但是理解它的机制是很酷的。

    printf
    的参数格式字符串包含
    %s
    并且相应的参数不是指向以
    \0
    结尾的
    字符的指针时,程序的行为是
    未定义的

    通常
    std::string
    将包含一些指针,其中包含实际数据的信息(起始指针、结束指针/大小等),数据可能以null结尾,也可能不以null结尾。因此,尝试使用
    C
    函数打印
    std::string
    是一种未定义的行为。(注意:
    std::string::c_str
    的类型是
    const char*
    并以null结尾,因此可以使用
    printf
    打印)


    printf
    无法在编译时检查参数的有效性,它会使用参数。如果它读取的数据不可读,陷阱实现可能会被实现,也可能会崩溃或按预期工作。

    C++03标准表示,将非POD的内容传递给varargs(…)参数是未定义的行为。事实上,gcc会警告您程序将崩溃(但无论如何编译成功)

    具体来说,这意味着

    printf("This doesn't use the arguments", std::string(""));
    
    可能会崩溃

    顺便说一句,在C++11中,用实现定义的语义定义的实现有条件地支持这一点,但仍然在“最好避免”下


    没有任何机制,也不能保证任何特定的行为。它可能会崩溃,可能会工作,可能会重新格式化你的硬盘。查看特定编译器正在执行的操作真的不有趣。

    将在运行时进行核心处理
    请从了解核心转储实际上是什么开始,而不是使用“to core”作为动词。并且printfs不会在stackptr处“引发非法指令”@其中是函数指针。。。而且这种行为只是UB,不能保证有任何特定的错误。会吗?我在不久的将来会看到鼻魔。@richard.g正如我刚才对stackptr所说的,不能保证有任何特定的错误。任何事情都有可能发生。有时它甚至可以正常工作。忽略警告通常是个坏主意,尤其是在警告很多的情况下。不能在C中打印std::字符串。C没有std::string@TomTanner你是对的。我的观点是使用C标准函数。让我重新解释一下。@MohitJain有关于“程序行为未定义”部分的文档吗?