0

これがビジュアル スタジオで正常にコンパイルおよび実行されるのに、GNU C++ コンパイラをコンパイルするとセグメンテーション エラーで失敗する理由を教えてください。

私の人生でこれを理解することはできません。前置/後置演算子を調べて確認し、イテレータが条件文に適切に配置されていることを確認しました...何が欠けていますか? 通常、動的配列の割り当て/割り当て解除を行っているときにこの問題が発生しますが、ここでは行っていません。

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <random>
#include <unordered_set>

namespace std{
    template <>
   struct hash<vector<int>> : public unary_function<vector<int>, size_t>
   {
       size_t operator()(const vector<int>& v) const
       {
           return v.size();
       }
   };
}

using namespace std;

struct testCase{
    int n; 
    int m;
    vector <int> wordVector; 
};

bool lexOrderConfirm(std::vector<int>::const_iterator, std::vector<int>::const_iterator, std::vector<int>::const_iterator, int ); 

int main() {    

int t; 

cin>>t;
vector <testCase*> testCaseVector(t);

for (int i = 0; i < t; ++i){

     testCaseVector[i] =  new testCase;

     cin>>testCaseVector[i]->n; 
        cin>>testCaseVector[i]->m;

}




         for (int i = 0; i < t; ++i){


            std::unordered_set<std::vector<int>, std::hash<std::vector<int> > >permutations;

             int permu = pow((double)testCaseVector[i]->n, testCaseVector[i]->m); 





int count = 0;



      for (int z= 0;  z < (permu*10); ++z){
      std::random_device rd;

    std::default_random_engine randomeng( rd() );
     int v;
      for (int b = 0; b < testCaseVector[i]->m; ++b){
     v= randomeng() % testCaseVector[i]->n + 1;   /*random number between 1 and n*/
     testCaseVector[i]->wordVector.push_back(v);
      }
      std::sort(testCaseVector[i]->wordVector.begin(), testCaseVector[i]->wordVector.end());

      permutations.insert(testCaseVector[i]->wordVector);
      testCaseVector[i]->wordVector.clear();
      }



      do {

           vector <int> test = *permutations.begin();

        do {
                std::vector<int>::const_iterator start = test.begin();
            std::vector<int>::const_iterator end;

                end = test.end();

            std::vector<int>::const_iterator lastElem = start+(testCaseVector[i]->m-1);


            if (lexOrderConfirm(start, end, lastElem, testCaseVector[i]->n)){
                ++count;
            }


        }while(std::next_permutation(test.begin(),test.end()));

        permutations.erase(permutations.begin());
        test.clear();
      }while(!permutations.empty());







  count = count%100000007;
        cout<<count<<endl;



         }
    return 0;

}


bool lexOrderConfirm(std::vector<int>::const_iterator start, std::vector<int>::const_iterator end, std::vector<int>::const_iterator lastElem, int N){
  bool confirmed = true;

  for (std::vector<int>::const_iterator t = start; t != end; ++t){
                if ((2* (*t) > N)){


               } else if ((2*(*t) <= N) && (*(t+1) >= 2 * (*t)) && (t != (lastElem))){



                }else{
                    confirmed = false;
                    break;
               }

    }

  return confirmed;
}
4

1 に答える 1

1

もちろん、その理由は、初期化されていないポインターを逆参照しているためです。ユーザー入力に依存しているため、現在のコードからはわかりません。私にとってはうまくいくようですt = 2; 想定どおりに機能しているかどうかはわかりませんが。

しかし、なぜ Visual Studio で実行されるのでしょうか?

VC++ポインタを NULL に初期化しないためです。初期化されていないポインターが指すものは、初期化されたポインターと同じように機能しているため、機能しています。したがって、基本的に未定義の動作です。

GNU C++ コンパイラをコンパイルすると、セグメンテーション違反で失敗するのはなぜですか?

g++ポインタをNULLに初期化するため

于 2013-04-15T01:01:34.883 に答える