Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.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:ostringstream和-std=c+的内存错误+;11?_C++_C++11_Memory Leaks_Stringstream_Temporary Objects - Fatal编程技术网

C++ std:ostringstream和-std=c+的内存错误+;11?

C++ std:ostringstream和-std=c+的内存错误+;11?,c++,c++11,memory-leaks,stringstream,temporary-objects,C++,C++11,Memory Leaks,Stringstream,Temporary Objects,编辑:感谢所有指出问题的人,并在堆栈溢出问题上进行了讨论。我自己投了最后一票 一个相关的问题:CPP既没有提及也没有说明其是临时的。那么多人怎么知道的?或者我是否应该查阅不同的文件 我在使用GCC4.7.2的Debian 7.3(x64)下的内存错误方面遇到了很多麻烦,-std=c++11和std::ostringstream。它会导致类似这样的商业结果 完整的程序使用Sqlite。与Valgrind相比,从命令行运行简化案例会打印出两个不同的错误。整个简化案例程序可以在(我认为在这里发布整个

编辑:感谢所有指出问题的人,并在堆栈溢出问题上进行了讨论。我自己投了最后一票

一个相关的问题:CPP既没有提及也没有说明其是临时的。那么多人怎么知道的?或者我是否应该查阅不同的文件


我在使用GCC4.7.2的Debian 7.3(x64)下的内存错误方面遇到了很多麻烦,
-std=c++11
std::ostringstream
。它会导致类似这样的商业结果

完整的程序使用Sqlite。与Valgrind相比,从命令行运行简化案例会打印出两个不同的错误。整个简化案例程序可以在(我认为在这里发布整个示例有点长)。它所做的只是初始化Sqlite、打开数据库、创建表、关闭数据库并统一数据库。如果发生错误,它会报告错误。没有别的事情发生

下面是简化案例程序的一部分,它只是尝试创建一个表。如果该表存在,则应产生一个错误(确实如此):

在Valgrind下,信息是:

sqlite3_exec failed, error 1
Sqlite error: table 
sqlite3_exec failed, error 1
Sqlite error: table test already exists

该程序大量使用了
ostringstream
,Valgrind围绕它们产生了近13个问题,其中9个问题包括底层
基本字符串上的
运算符删除(void*)
。例如,下面显示了一个(来自
t.cpp
的第76行是
const char*stmt=qs.str().c_str();
):

==14318==大小为1的无效读取
==14318==at 0x45ACC8:sqlite3\u exec(sqlite3.c:94542)
==14318==0x405D07:main(t.cpp:79)
==14318==地址0x5d89728是大小为127 free'd的块中的24个字节
==14318==0x4C27870处:运算符删除(void*)(vg_replace_malloc.c:502)
==14318==by 0x530EB1F:std::basic_string::~basic_string()(in/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
==14318==0x405CF1:main(t.cpp:76)
有人知道这里发生了什么吗?它是ostringstream吗?或者GCC 4.7.2?或者Debian的港口


(对于这个开放式问题,我感到很抱歉。我已经没有事情可做了)。

仔细看看这一行:
const char*stmt=qs.str().c_str()

qs.str()。一旦这一行完成执行,指针就不再有效,其他东西可能(也可能)存储在那里

尝试这样做:

std::string strstmt(qs.str());
const char* stmt = strstmt.c_str();

仔细看看这一行:
const char*stmt=qs.str().c_str()

qs.str()。一旦这一行完成执行,指针就不再有效,其他东西可能(也可能)存储在那里

尝试这样做:

std::string strstmt(qs.str());
const char* stmt = strstmt.c_str();
它从
qs
中提取一个临时字符串,获取指向其内容的指针,然后销毁临时字符串,使指针悬空。在此之后使用指针将给出未定义的行为

要修复它,您可以将
str()
的结果赋给一个变量,这样它就不再是临时的,或者使用此表达式作为
sqlite3_exec
的参数,这样临时的结果在该函数调用之后仍然有效。(在第二种情况下,您必须删除第一个断言;但该断言无论如何都是毫无意义的)

它从
qs
中提取一个临时字符串,获取指向其内容的指针,然后销毁临时字符串,使指针悬空。在此之后使用指针将给出未定义的行为


要修复它,您可以将
str()
的结果赋给一个变量,这样它就不再是临时的,或者使用此表达式作为
sqlite3_exec
的参数,这样临时的结果在该函数调用之后仍然有效。(在第二种情况下,您必须删除第一个断言;但该断言无论如何都是毫无意义的)。

const char*stmt=qs.str().cstr()坏。@Simple让我们看看谁是第一个找到重复项的;)我知道这不是答案,但是
str()
返回一个缓冲区副本,这样做
str()。reserve(x)
是徒劳的。是的,我想知道这是什么:
str()。reserve(x)
doing@noloader是的。请注意,返回类型是
string
而不是
string&
。明确提到了这个可能的错误。
const char*stmt=qs.str().c_str()坏。@Simple让我们看看谁是第一个找到重复项的;)我知道这不是答案,但是
str()
返回一个缓冲区副本,这样做
str()。reserve(x)
是徒劳的。是的,我想知道这是什么:
str()。reserve(x)
doing@noloader是的。请注意,返回类型是
string
而不是
string&
。明确提到了这个可能的错误。谢谢迈克。现在我知道发生了什么,我就能解决问题了。相关报道:人们是如何知道这是暂时的(他们是在过去被烧死的,还是只是常识)?我使用的两个引用没有说明这是一个临时对象。是C++标准规定的行为吗?@诺洛德:我不能为人们说话,但我通过这样被烧毁来了解暂时性的东西。它的指定行为是:
str()
按值返回字符串;返回值是临时的;临时变量在创建它们的完整表达式的末尾被销毁(这里不适用一个例外)。谢谢Mike。现在我知道发生了什么,我就能解决问题了。相关报道:人们是如何知道这是暂时的(他们是在过去被烧死的,还是只是常识)?我使用的两个引用没有说明这是一个临时对象。这种行为是特定的吗
std::string strstmt(qs.str());
const char* stmt = strstmt.c_str();
const char* stmt = qs.str().c_str();