将一个std::字符串复制到另一个时出现段错误
Segfault on copying one std::string to another?
我有以下类:
class StdinIo : public FileIo{
public:
StdinIo();
~StdinIo();
static StdinIo* createObj(const std::string&);
static bool checkPath(const std::string&);
private:
std::string tempPath;
std::string newPath();
};
实现1:StdinIo::StdinIo()
:FileIo(newPath())
{
}
std::string StdinIo::newPath(){
printf("%s Using FileIon", __PRETTY_FUNCTION__);
std::stringstream tempPathStream;
tempPathStream << tmpnam(NULL) << getpid();
tempPathStream.flush();
const char* szTempPath = tempPathStream.str().c_str();
FILE *fp=fopen(szTempPath,"wb");
size_t rv=1;
char buffer[1024*8];
if(fp){
while(rv){
rv=fread(buffer,1,sizeof(buffer),stdin);
fwrite(buffer,1,rv,fp);
}
fclose(fp);
}
return tempPathStream.str();
}
实现2:StdinIo::StdinIo()
:FileIo(newPath())
{
}
std::string StdinIo::newPath(){
printf("%s Using FileIon", __PRETTY_FUNCTION__);
std::stringstream tempPathStream;
tempPathStream << tmpnam(NULL) << getpid();
tempPathStream.flush();
tempPath = tempPathStream.str();
const char* szTempPath = tempPath.c_str();
FILE *fp=fopen(szTempPath,"wb");
size_t rv=1;
char buffer[1024*8];
if(fp){
while(rv){
rv=fread(buffer,1,sizeof(buffer),stdin);
fwrite(buffer,1,rv,fp);
}
fclose(fp);
}
return tempPath;
}
根据我对栈的了解,实现1应该给出一个segFault,而实现2不应该。但情况正相反。我不知道为什么。
我需要tempPath字符串作为类成员,以便稍后可以在析构函数中删除该文件。
StdinIo::~StdinIo(){
if( unlink(tempPath.c_str()) != 0 )
perror( "Error deleting file" );
}
在注释掉这里和那里的行之后,我发现在下一行出现了段错误:
tempPath = tempPathStream.str();
gdb说:
Program received signal SIGSEGV, Segmentation fault.
__exchange_and_add_dispatch (__mem=0xfffffffffffffff8, __val=<optimized out>)
at /usr/src/debug/gcc-4.7.2-20120921/obj-x86_64-redhat-linux/x86_64-redhat- linux/libstdc++-v3/include/ext/atomicity.h:83
83 return __exchange_and_add_single(__mem, __val);
在对象完全初始化之前,第二个实现调用newPath()
并访问tempPath
(将其传递给基类构造函数)。这将导致未定义的行为。
如果你绝对需要文件名的本地副本,而不需要对现有代码进行重大更改,你可以使用实现#1。
class StdIoSpecialData : public FileIo
{
protected:
StdIoSpecialData(const std::string &fname)
: FileIo(fname),
tempPath(fname)
{
}
const std::string tempPath;
};
class StdIo : public StdIoSpecialData
{
public:
StdIo()
: StdIoSpecialData(newPath())
{
}
};
相关文章:
- 两个线程一个使用流 Api,另一个线程创建文件失败并出现错误ERROR_SHARING_VIOLATION
- 如何正确实例化静态字段 tat 是另一个类对象
- 使用另一个函数调用一个函数(都在类中)时出现问题.没有错误代码C++
- 在使用另一个类"friend"函数时无法发现错误C++
- ::grpc::ServerReaderWriter 对象在另一个线程中一段时间后无法调用
- 包含来自另一个文件的函数会导致范围错误(openFoam)
- C:试图将指针值复制到另一个指针中,得到可修改的左值错误
- 从一个类访问私有字段到另一个与C++中的前一个类无关的私有字段 (OOP)
- 在另一个结构中声明内部结构会导致错误:结构使用无效
- 尝试向 COM 对象添加另一个接口时出现静态强制转换错误 C2440
- 返回带有另一个类的数据成员的构造函数?遇到转换错误?
- 向量迭代器不兼容的错误,用于保存另一个向量的迭代器的向量
- 将 std::string 作为参数从一个 DLL 传递到另一个 DLL 引发访问冲突错误
- 访问另一个类(系统)的非静态字段,就好像它是我自己的字段一样 - 优雅地
- 使用声明:GCC 和 Clang 的另一个错误?
- 调用方法,该方法修改字段,而使用该字段的另一个方法正在执行
- 查找哪个代码段比另一个代码段快
- 在一个结构中,使用一个数组字段访问另一个是否合法
- 使用 gtest EXPECT_CALL 时竞争条件段错误,而另一个期望是执行相同的方法
- 将一个std::字符串复制到另一个时出现段错误