使用 std::string.c_str() 作为另一个方法的参数时的段错误
Posted
技术标签:
【中文标题】使用 std::string.c_str() 作为另一个方法的参数时的段错误【英文标题】:Segfault when using std::string.c_str() as an argument for another method 【发布时间】:2013-11-20 18:06:58 【问题描述】:谁能告诉我为什么使用 c_str() 返回的 const char* 作为 stat(const char*, stat*) 中的参数会导致程序出现段错误?我想我已经将我的段错误缩小到由那条线引起的,但我不确定用什么来代替。我尝试使用 strcpy() 将字符串复制到字符数组中,但这只是导致程序在方法返回时出现段错误,这并没有好多少。
DIR * dir_p;
struct dirent *dir_entry_p;
list<string> files;
dir_p = opendir(".");
//push all file names to a list
while((dir_entry_p = readdir(dir_p))!=NULL)
string name = dir_entry_p->d_name;
files.push_front(name);
closedir(dir_p);
files.sort();
//count total blocks
//iterate through list
map<string,struct stat*> fileStats;
struct stat * entry;
for(list<string>::iterator it = files.begin(); it != files.end(); it++)
stat(it->c_str(),entry);
fileStats[*it]=entry;
cout<<entry->st_blocks<<" "<<*it<<endl;
【问题讨论】:
使用所有警告和调试信息进行编译(例如使用g++ -Wall -g
)。改进代码直到没有给出警告。使用valgrind 和您的调试器(例如gdb
)
@H2CO3,我愿意接受有关如何避免“未格式化、无法阅读的混乱”的建议。简单地说它是这样的,这不是我以后编写代码时可以考虑的事情。事实上,您的评论毫无帮助且具有煽动性。
【参考方案1】:
我不认为这是 c_str()
在这里制造麻烦,而是您如何使用 struct stat
。
你应该创建一个struct stat
实例并传递它的地址:
// ...
//iterate through list
map<string,struct stat> fileStats;
for(list<string>::iterator it = files.begin(); it != files.end(); it++)
struct stat entry;
stat(it->c_str(),&entry);
fileStats[*it]=entry;
cout<<entry.st_blocks<<" "<<*it<<endl;
您正在做的是让stat()
写入来自未初始化指针的地址(这很可能会导致段错误)。
请注意,您还需要更改地图类型才能使其正常工作。
【讨论】:
@Dazedy 注意如何初始化指针(内存泄漏等)。我发布的代码应该可以正常工作,并且不会增加任何额外的开销。以上是关于使用 std::string.c_str() 作为另一个方法的参数时的段错误的主要内容,如果未能解决你的问题,请参考以下文章
std::string::c_str() 覆盖函数返回的前一个
C++string类型与C语言字符数组的转换 std::string.c_str()函数
std::string::c_str() 结果的生命周期是多少?
std::string::c_str() 结果的生命周期是多少?