Segmentation Fault Strongly Because of Heap/Stack Corruption

ε祈祈猫儿з 提交于 2019-12-25 05:12:05

问题


#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 for pasting whole the code, i am getting a seg fault in main, on line

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

Can you have an idea? Also can you advise a debugging tool beside gdb on linux, ubuntu? Especially to see memory corruptions?

Thanks in advance.


EDIT

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:

in main function;

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

                  }

to put sth to a specific index at vector

c++ insert into vector at known position


回答1:


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.

If you are trying to insert default Element into the vector, use the vector::resize method instead of reserve.



来源:https://stackoverflow.com/questions/10565209/segmentation-fault-strongly-because-of-heap-stack-corruption

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!