分段故障强烈由于堆/堆栈损坏 [英] Segmentation Fault Strongly Because of Heap/Stack Corruption

查看:249
本文介绍了分段故障强烈由于堆/堆栈损坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#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

c ++已插入到向量中位置

推荐答案

您正在遍历向量在循环中插入同一个向量。当插入向量时,由于向量重新分配,向量 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆