分段故障强烈由于堆/堆栈损坏 [英] Segmentation Fault Strongly Because of Heap/Stack Corruption
问题描述
#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <string>
#include <stdlib.h>
#include <limits.h>
#include <list>
#include <math.h>
#include <vector>
#include <iostream>
using namespace std;
enum ElementType { NONE,SIMPLEFILE, DIRECTORY, SYMBOLICLINK };
class Element{
public:
Element():exists(false){
name=std::string("");
full_path_name=std::string("");;
element_type=NONE;
element_size=0;
exists=false;
};
std::string name;
std::string full_path_name;
ElementType element_type;
long element_size;
bool exists;
};
int inspect( std::list<Element>& result_element_array, long *dir_size,std::string full_path ) {
std::list<Element> result_element_array_temp;
result_element_array.clear();
DIR *d;
struct dirent *dir;
struct stat buf;
std::string mynamebuf;
long dir_size_temp=0;
std::string full_path_temp;
std::string full_path_dummy;
d = opendir( full_path.c_str());
if( d == NULL ) {
return 1;
}
while( ( dir = readdir( d ) )) {
if( strcmp( dir->d_name, "." ) == 0 ||
strcmp( dir->d_name, ".." ) == 0 ) {
continue;
}
mynamebuf=full_path;
mynamebuf+=std::string(full_path.at(full_path.size() - 1) == '/' ? "" : "/");
mynamebuf+=std::string(dir->d_name);
if (stat(mynamebuf.c_str(), &buf) != 0) {
perror(mynamebuf.c_str());
continue;
}
if( S_ISDIR(buf.st_mode) ) {//if dir
chdir( dir->d_name );
full_path_temp=full_path;
full_path_temp+=std::string("/");
full_path_temp+=std::string(dir->d_name);
(dir_size_temp)=0;
inspect(result_element_array_temp, &dir_size_temp, full_path_temp );
chdir( ".." );
full_path_dummy=full_path_temp;
Element element;
element.name=dir->d_name;
element.full_path_name=full_path_dummy;
element.element_type=DIRECTORY;
element.element_size=dir_size_temp;
element.exists=true;
result_element_array.push_back(element);
result_element_array.insert( result_element_array.end(), result_element_array_temp.begin(), result_element_array_temp.end() );
(*dir_size)+=(dir_size_temp);
}else if( S_ISREG(buf.st_mode)) {//if file
full_path_dummy=full_path;
full_path_dummy+=std::string("/");
full_path_dummy+=std::string(dir->d_name);
Element element;
element.name=dir->d_name;
element.full_path_name=full_path_dummy;
element.element_type=SIMPLEFILE;
element.element_size=buf.st_size;
element.exists=true;
result_element_array.push_back(element);
(*dir_size)+=buf.st_size;
} else if( S_ISLNK(buf.st_mode) ) {//if link
full_path_dummy=full_path;
full_path_dummy+=std::string("/");
full_path_dummy+=std::string(dir->d_name);
Element element;
element.name=dir->d_name;
element.full_path_name=full_path_dummy;
element.element_type=SYMBOLICLINK;
element.element_size=0;
element.exists=true;
result_element_array.push_back(element);
} else {
continue;
}
}
closedir(d);
return 0;
}
int prime(int n) {
int i=0;
double sqrt_n = sqrt(static_cast<double>(n));
for (i = 2; i <= sqrt_n; i++) {
if (n % i == 0)
return false;
}
return true;
}
int stringIntValue(std::string key){
int code=0;
for(int i=key.size()-1;i>=0;i--){
code+=key.at(i)*i;
}
return code;
}
int findmforhash(int sizeoflist){
int m=sizeoflist;
if(m % 2 !=1){ m++;}
while(m<sizeoflist*2 && !prime(m)){
m+=2;
}
return m;
}
int hash_func(int keyIntValue, int m, int i){
int code=((keyIntValue % m)+(i*(keyIntValue%(m-2)))%m);
return code;
}
void locatetohashtable(std::list<Element> elist,int m,std::vector<Element>& table, std::list<std::string>& keylist ){
std::vector <Element>::iterator It2=table.begin();
int i=0;
int k=0;
std::list <Element>::iterator It;
for(It = elist.begin(); It != elist.end(); ++It){
int code=hash_func(stringIntValue((*It).name),m,i);
while((*(It2 + code)).exists){
i++;
}
table.insert((It2+code), (*It));
keylist.push_back((*It).name);
k++;
}
}
void usage(void)
{
printf("Usage:\n");
printf("./traversedir -d <directory_to_explore>\n");
exit (8);
}
void searchtable(std::string searchparam,std::vector<Element> table, std::list<std::string> keylist, int m ){
std::list <string>::iterator Itkey;
int code=0;
for(Itkey = keylist.begin(); Itkey != keylist.end(); ++Itkey){
if((*Itkey).find(searchparam)!=-1){
int j=0;
do{
code=hash_func(stringIntValue(*Itkey),m,j);
j++;
}while((*(table.begin()+code)).name.compare(*Itkey)!=0);
printf("%s",(*(table.begin()+code)).full_path_name.c_str());
printf("%ld",(*(table.begin()+code)).element_size);
printf("%d",(*(table.begin()+code)).element_type);
}
}
}
int main(int argc, char *argv[]){
if ((argc > 1) && (argv[1][0] == '-'))
{
switch (argv[1][1])
{
case 'd':
printf("\n");
if(argc>=3){
std::vector<Element> table;
std::list<std::string> keylist;
std::list<Element> result_element_array;
int m;
long dir_size=0;
inspect( result_element_array, &dir_size,std::string(argv[2]) );
m=findmforhash(result_element_array.size());
table.reserve(m);
std::vector <Element>::iterator It;
for(It = table.begin(); It != table.end(); ++It){
Element element;
element.exists=false;
table.insert(It, element);
}
locatetohashtable(result_element_array, m, table, keylist );
std::string searchparam;
printf("Please enter a file name:");
std::cin >> searchparam ;
searchtable(searchparam,table, keylist, m );
}
case 'h':
usage();
break;
default:
printf("Wrong Argument: %s\n", argv[1]);
usage();
}
}else {
usage();
}
return 0;
}
SOrry用于粘贴整个代码,
SOrry for pasting whole the code, i am getting a seg fault in main, on line
for(It = table.begin(); It != table.end(); ++It){
你有想法吗?也可以建议一个调试工具gdb on linux,Ubuntu?特别是看到内存损坏?
Can you have an idea? Also can you advise a debugging tool beside gdb on linux, ubuntu? Especially to see memory corruptions?
提前感谢。
EDIT
感谢Naveen,我编辑了代码,并且该文件正常工作
更改为不使用向量您在该向量上迭代的循环:
THanks to Naveen, , I edited the code and that piece is working correctly Changed for not to use vector inside the loop that you iterate over that vector:
在主函数中;
table.resize(m);
for(int y=0;y<m;y++){
Element element;
element.exists=false;
table.push_back(element);
}
将sth添加到向量的特定索引
to put sth to a specific index at vector
推荐答案
您正在遍历向量
在循环中插入同一个向量
。当插入向量时,由于向量重新分配,向量 It
可能会失效。所以当你做 It ++
它会崩溃。
You are iterating through the vector
and inserting into the same vector
inside the loop. When you insert into the vector, the vector It
might become invalid due to vector reallocation. So when you do It++
it will crash.
如果你试图插入默认元素
到向量中,使用 vector :: resize
方法而不是 reserve
。
If you are trying to insert default Element
into the vector, use the vector::resize
method instead of reserve
.
这篇关于分段故障强烈由于堆/堆栈损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!