Question

The question title may seem odd but this seems to be a strange bug in my code that I can't quite figure out.

      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 }

The declaration of the 2-D double array causes me to get the following error when executing the next std::cin.getline() statement in 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();

It seems to work fine if I use only the extern dist variable. Also it works perfectly if I keep the declaration of distance but do not use it in line number 30. Of course this is only a code snippet of my larger tsp.cc file. If anyone requires any more info, I'd be glad to provide it. I just hope I haven't missed something obvious in my sleep-deprived state. :)

I'm using gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-1ubuntu1)

Was it helpful?

Solution

The double distance[MAX_CITIES][MAX_CITIES] array is being allocated on the stack, and is causing your program to crash when something access the memory in the function.

This doesn't happen for the one outside the function because the compiler/linker allocates that block in the heap.

The solution is to dynamically allocate the memory (easiest is a single block):

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

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

delete[] distance;

Of course, this could still fail if MAX_CITIES is large, so then handle the failure gracefully.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top