2

I am solving a 0-1knapsack problem. I solved the problem by brute force algorithm.

In main.cpp

  int main(int argc, char *argv[])
  {
     ......
     int solution;
     solution = bruteForce();
     ......
  }

The strange thing is, when I implement the bruteForce() in main.cpp, my program works correctly, however, after I move the bruteForce() to bruteForce.cpp and included it in main.cpp, the program will produce segmentation fault when calling the bruteForce().

Here's how I move bruteForce() to bruteForce.cpp. First I created a header functions.h(because I want to solve the problem by other method after implement brute force successfully)

  functions.h:

  #include "global.h"
  int bruteForce();
  int multiplication( int );

And then I move bruteForce() to bruteForce.cpp

  #include <iostream>
  #include <stdlib.h>
  #include <vector>
  #include "global.h"
  #include "functions.h"

  using namespace std;

  int bruteForce()
  {
     int bestValue = 0;
     int j, tempSize, tempValue;
     int bestChoice[n+1];

     for(int i=0; i<multiplication(n); i++)
     {
         tempSize = 0;
         tempValue =0;
         j = n;

         while(x[j]!=0 && j>0)
         {
             x[j] = 0;
             j--;
         }
         x[j] = 1;

         for(int k=1; k<=n; k++)
         {
             if(x[k] == 1)
             {
                 tempSize += size[k];
                 tempValue += value[k];
             }
         }


        if((tempValue > bestValue) && (tempSize <= S)) 
        {   
            bestValue = tempValue;
            for(int p=1; p<=n; p++)
                bestChoice[p] = x[p];
        }
    }
    for(int p=1; p<=n; p++)
       x[p] = bestChoice[p];

    return bestValue;
 }

In global.h, I declared some glabal variables:

  #include <vector>
  using std::vector;

  static int n, S;
  static vector<int> value, size, x;

The gdb debugger shows

  Program received signal SIGSEGV, Segmentation fault.
  0x08049308 in main()

Any idea about why this happens?

Thanks in advance.

Oh BTW, if you need more info, here's the package. You can first type make in the root of this package. Then type this to execute.

  ./bin/01knapsack -BF inputs/n5S11.in n5s11.out
Po-Jen Lai
  • 411
  • 1
  • 8
  • 18
  • 2
    You should compile with `-ggdb` to get debugging symbols. Then you will be able to get a proper stack trace in GDB. – Oliver Charlesworth Mar 31 '12 at 13:45
  • It is due to memory issues while executing. Are you using any memory related statements like memcpy or something similar apart from the code given above? And try creating the files in a separate folder and exe it .May be the program block in your memory crashed or something. – Milee Mar 31 '12 at 13:46
  • 2
    Where and how do you declare x[], size[], and value[] arrays? – stanwise Mar 31 '12 at 13:47
  • Do you also have a file *bruteForce.h,* which you have *#included* both in *bruteForce.cpp* and in your driver? If so, then would you show how you have done this, so that we can check it? – thb Mar 31 '12 at 13:47
  • 3
    What is x? What is N? Why are you indexing fom 1..N, instead of from 0..N-1? – wildplasser Mar 31 '12 at 13:48
  • x[], size[], value[] are vectors with "n+1" elements. And I used from 1 to N. – Po-Jen Lai Mar 31 '12 at 13:52
  • Yes I have header file(but named "functions.h", because I want to solve the problem by other method after implement brute force successfully), and I included functions.h in bruteForce.cpp. – Po-Jen Lai Mar 31 '12 at 13:54
  • Thanks Oli and Sharmi, I'll try -ggdb. – Po-Jen Lai Mar 31 '12 at 14:12
  • @Ricky: You should define/declare your variables in the source, not in the comments. – wildplasser Mar 31 '12 at 14:16
  • @wildplasser: I declared them in global.h, I am not sure if the problem is caused by that. – Po-Jen Lai Mar 31 '12 at 14:29
  • 1
    The stack shows segmenation violation in main, why do you believe it happens due to this function? I would suggest running your program from debugger, and putting a break point just before calling the function, first see if you get to that point. – Alex Mar 31 '12 at 15:30

1 Answers1

2

You shouldn't put your variables in a header file. When you include that from both your source files, both will get their own individual copy of that variable - and thus you wont be able to transfer data between your functions in the way you think (or at least, that's my understanding of how it should work - I'll admit that I'm not 100% sure what actually happens).

The best way to transfer data to a function is to use parameters though. Call the function with whatever it needs, and return data either through the function return value, or through a pointer or reference parameter. Using global variables for stuff like this is error prone (as you have seen), and it's much less clear for others looking at your code.

If you absolutely want to use global variables, declare them in one of your source files, and put them in your global header file with an extern statement in front of it. When you then include the header from another file, extern tells the compiler that it shouldn't actually create the variable itself, but rather that it is provided by another object file.

So, in main.cpp:

int n, S;
vector<int> value, size, x;

And in global.h:

extern int n, S;
extern vector<int> value, size, x;
sonicwave
  • 5,952
  • 2
  • 33
  • 49