0

質問のタイトルは奇妙に思えるかもしれませんが、これは私のコードの奇妙なバグのようで、よくわかりません。

      1 #include "linkern.h"
      2 #include "linkern-inl.h"
      4 #include <iostream>
      5 #include "tsp.h" //contains macro MAX_CITIES
      6 
      7 extern bool euclidean;
      8 extern double dist[MAX_CITIES][MAX_CITIES];
      9 
     10 void LinKernighan::inputData()
     11 {
     12     char buf[20];
     13     int no_cities;
     14     double coords[MAX_CITIES][2];
     15     double distance[MAX_CITIES][MAX_CITIES]; //works fine if this is commented out
     16     std::cin.getline(buf, 20);
     17     if (buf[0] == 'e') // if euclidean TSP
     18         euclidean = true;
     19     else
     20         euclidean = false;
     21     std::cin>>no_cities;
     22     Tour::NUM_CITIES = no_cities;
     23     nearest_neighbours.reserve(Tour::NUM_CITIES);
     24     for (int i=0; i<Tour::NUM_CITIES; i++)
     25         std::cin>>coords[i][0]>>coords[i][1];
     26     for (int i=0; i<Tour::NUM_CITIES; i++)
     27     {
     28         for (int j = 0; j < Tour::NUM_CITIES; ++j)
     29         {
     30             std::cin>>distance[i][j]; //works fine if this is commented out
     31             //dist[i][j] = round(dist[i][j]);
     32         }
     33     }
     34 }

2 次元 double 配列の宣言により、std::cin.getline()gdb で次のステートメントを実行すると、次のエラーが発生します。

Program received signal SIGSEGV, Segmentation fault.
0x000000000040245e in widen (__c=10 '\n', this=0x7ffff7dd7d60) at /usr/include/c++/4.7/bits/locale_facets.h:871
871     this->_M_widen_init();

extern dist変数のみを使用するとうまくいくようです。また、30 行目での宣言をdistanceそのまま使用しても、完全に機能します。もちろん、これは、より大きな tsp.cc ファイルのコード スニペットにすぎません。誰かがさらに情報を必要とする場合は、喜んで提供します。睡眠不足の状態で明らかな何かを見逃していないことを願っています. :)

gcc バージョン 4.7.3 (Ubuntu/Linaro 4.7.3-1ubuntu1) を使用しています。

4

1 に答える 1

1

配列がスタックに割り当てられており、double distance[MAX_CITIES][MAX_CITIES]何かが関数内のメモリにアクセスすると、プログラムがクラッシュします。

コンパイラ/リンカーがそのブロックをヒープに割り当てるため、これは関数の外側のブロックでは発生しません。

解決策は、メモリを動的に割り当てることです (最も簡単なのは単一のブロックです)。

double *distance = new double[MAX_CITIES*MAX_CITIES];

some_value = distance[(i*MAX_CITIES)+j];

delete[] distance;

もちろん、MAX_CITIES が大きい場合は失敗する可能性があるため、失敗を適切に処理してください。

于 2013-10-11T13:06:42.423 に答える