0
#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;
      }

抱歉粘贴了整个代码,我在主线上遇到了段错误

                  for(It = table.begin(); It != table.end(); ++It){

你能有个主意吗?您还可以建议在 linux、ubuntu 上的 gdb 旁边的调试工具吗?特别是看到内存损坏?

提前致谢。


编辑

感谢 Naveen,我编辑了代码并且该部分工作正常更改为不在循环内使用向量,您迭代该向量:

在主函数中;

table.resize(m);
                  for(int y=0;y<m;y++){
                    Element element; 
                    element.exists=false;
                        table.push_back(element);

                  }

将某物放在向量处的特定索引上

c++ 在已知位置插入向量

4

1 回答 1

7

您正在循环中迭代vector并插入到相同vector的循环内。当您插入向量时,It由于向量重新分配,向量可能会变得无效。所以当你这样做时It++它会崩溃。

如果您尝试将默认值Element插入向量中,请使用该vector::resize方法而不是reserve.

于 2012-05-12T16:08:01.163 回答