-2

I have a segmentation fault 11 in this piece of code (edit:no longer shown).

Having been told to get a debugger and to sort my arrays out I have edited the code to fix the arrays to go from 0. I also installed valgrind and ran it but it is limited when working on OSX. I have run gbd and the issue is described below.

If this just looks horrendously ominous, or the code is needed to make any kind of headway, let me know and I can edit the question to the format the forum expects.

Running gdb on my code I get:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00007fff5e4c27c8
0x0000000100001048 in main () at TammesA3.cc:23
23    mpf_set_default_prec(1024);

The code is as follows and the issue is caused before my loops later on even start!

#include <stdio.h> 
#include <string.h>
#include <math.h>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <time.h>
#include <stdlib.h>
#include <sstream>
#include <gmpxx.h>
using namespace std;
#define PI 3.14159265358979323846

mpf_t E[100000];

int main()
{

  int a,b,c,d,f,i,j,k,m,n,s,Success,Fails;
  double p,theta,phi,Time,Averagetime,Distance,Length,DotProdForce,
         Forcemagnitude,ForceMagnitude[200],Force[200][3],Epsilon[3],
         x[200][3],new_x[200][3],y[200][3],A[200],alpha[200][200],degree,bestalpha[500];
  unsigned long int t;

  mpf_set_default_prec(1024);

  mpf_t Energy,energy,Power,D,En[500],Ep,e;

  mpf_init(Power);
  mpf_init(D);
  mpf_init(Ep);
  mpf_init(e);
  mpf_init(Energy);
  mpf_init(energy);

  for(i=0;i<100000;i++){
   mpf_init(E[i]);
  }

  for(i=0;i<500;i++){
    mpf_init(En[i]);
  }

  mpf_set_d(e,0.00000000000000000000000000000000000000000000000000000000001);

  clock_t t1,t2;
  t1=clock();

t=1000;

while(t<1001){

n=20;

while(n<21){

cout << "N=" << n << "\n";

  b=1;
  Time=0.0;

  while(b<2){

    clock_t t3,t4;
    t3=clock();

    if(n>200){
      cout << n << " is too many points for me :-( \n";
      exit(0);
    }

    srand((unsigned)time(0));  

    for (i=0;i<n;i++){
      x[i][0]=((rand()*1.0)/(1.0*RAND_MAX)-0.5)*2.0;
      x[i][1]=((rand()*1.0)/(1.0*RAND_MAX)-0.5)*2.0;
      x[i][2]=((rand()*1.0)/(1.0*RAND_MAX)-0.5)*2.0;

      Length=sqrt(pow(x[i][0],2)+pow(x[i][1],2)+pow(x[i][2],2));

      for (k=0;k<3;k++){
        x[i][k]=x[i][k]/Length;
      }
    }

    for(i=0;i<n;i++){
      for(j=0;j<3;j++){
        cout << "x[" << i << "][" << j << "]=" << x[i][j] << "\n";
      }
    }

    /* Points distributed randomly and normalised so they sit on unit sphere */

    mpf_set(Energy,0);

    for(i=0;i<n;i++){
      for(j=i+1;j<n;j++){
        Distance=sqrt(pow(x[i][0]-x[j][0],2)+pow(x[i][1]-x[j][1],2)
                     +pow(x[i][2]-x[j][2],2));

        mpf_set_d(D,Distance);

        mpf_pow_ui(Power,D,t);      
        mpf_ui_div(Power,1.0,Power);
        mpf_add(Energy,Energy,Power);

      }
    } etc.

after this, my code goes on into a loop, but the code as said in comments in really long so shan't put it in again unless requested.

adrem7
  • 388
  • 1
  • 3
  • 14
  • `int tab[10]` means 10 elements numbered 0, ... 9. – Marc Glisse Apr 01 '13 at 21:48
  • 2
    That's 555 lines of code. What do you expect us to do with it? – Gabe Apr 01 '13 at 21:49
  • @Gabe I know, I am sorry it is messy and unsophisticated, but I struggle with coding and have tried to piece together my knowledge to makes this. I don't even know what set fault 11 means, and from searching it always means something different. I was hoping someone with more knowhow might be able to spot something obvious. – adrem7 Apr 01 '13 at 21:56
  • @MarcGlisse I am sorry, but I don't know what that means. int is used as my main function (no idea why) and to declare integers, and I don't have tab anywhere in my code... – adrem7 Apr 01 '13 at 22:01
  • Segfault 11 means you're using memory you haven't assigned. About what Marc wrote: in C arrays are 0-based, so if your array has 10 elements, their have indexes are 0-9, so you can safely loop `for(i=0;i<10;i++)`. To check exactly which line creates segfault, you may use Valgrind (or properly debug app). – mrówa Apr 01 '13 at 22:08
  • @mrówa Oh I see, is there really an issue with just shifting everything up one though? If I have E[101] defined and a loop for(i=1;i<=501;i++) the <= just deals with the fact that the arrays start from 1 not 0 right? – adrem7 Apr 01 '13 at 22:17
  • 1
    You're systematically overstepping array bounds. You declare for example `mpf_t En[501]` and `mpf_init(En[i])` for `0 <= i < 502`. The last index you `mpf_init()` is 501, but the last valid index in the array is 500. – Daniel Fischer Apr 01 '13 at 22:17
  • @DanielFischer Altering the code to just initialise up to 500 still give the seg fault though (the code has been altered for those two in the original post). – adrem7 Apr 01 '13 at 22:42
  • 1
    -1. This problem could be trivially solved with a debugger and a basic understanding of how arrays work. – fluffy Apr 01 '13 at 22:43
  • @fluffy not knowing what you are doing is not a crime, if you told me how arrays worked (like those above) and told me where to get a debugger (looking into Valgrind since it was mentioned) then I won't make the mistake again... – adrem7 Apr 01 '13 at 22:46
  • @adrem7 It's not a crime but neither is the comment I posted. What debugger to use depends on what platform you're on, and you don't provide any informationa bout that. You haven't even done a basic job of isolating the problem down into the minimum necessary of finding the problem. The StackOverflow community is not your first-year CS professor. – fluffy Apr 01 '13 at 22:51
  • @fluffy I haven't done CS before and need to get this code running for my dissertation. I am installing valgrind now (using mac os 10.8.3) and shall keep working on the issue I have. I don't expect to be spoon fed, but obviously not what knowing what I am doing it has come across that way, my apologies. – adrem7 Apr 01 '13 at 23:01
  • "WARNING: Support on MacOS 10.8 is experimental and mostly broken." <- Unfortunately, as far as I know, it is indeed very unreliable on 10.8. If you have access to a Linux box, running valgrind there should give more reliable info. – Daniel Fischer Apr 02 '13 at 09:01
  • @DanielFischer I don't I'm afraid,, is there another debugger you would reccommend for OSX?? – adrem7 Apr 02 '13 at 09:27
  • Well, valgrind isn't quite what I'd call a debugger, it's for detecting memory leaks and invalid memory accesses (which are the primary cause of segfaults, so it's appropriate to use valgrind here). To find the cause of the segfault, you can also use a debugger, e.g. gdb - not 100% sure that has no problems with OS X, but I don't remember hearing of any. Compile the code with `-g`, run it under gdb until it gets the segfault, then gdb should tell you the offending line. – Daniel Fischer Apr 02 '13 at 09:37
  • @DanielFischer Thanks, I have edited the question accordingly. – adrem7 Apr 02 '13 at 10:01
  • If it segfaults on `mpf_set_default_prec`, my guess is that you have a stack overflow. `E[1000000]` could easily demand more than the stack has. You can try a) `ulimit -s unlimited` to make the stack size unlimited before running the programme [not good for a permanent solution, but a quick way to check whether that's the (only?) problem], b) making the arrays - at least the bigger ones - static by declaring them outside `main` so that they don't get put on the stack, c) allocating the arrays dynamically with `malloc` or `new`. – Daniel Fischer Apr 02 '13 at 10:47
  • @DanielFischer I have put the array outside the main and it did run, but only down to setting the Energy to 0 (line 94 for me), I think there are real issues with the floats from the gmp library, as when I remove that line (it was initialised and so set to 0 at that point anyway) the next error is the line below on another mpf_set... – adrem7 Apr 02 '13 at 10:57

1 Answers1

1

The remaining problem(1) is (on three lines)

mpf_set(Energy,0);

Its prototype is

void mpf_set (mpf_t ROP, mpf_t OP)

and an mpf_t is an array,

typedef __mpf_struct mpf_t[1];

so you pass a null pointer for the value to read. Dereferencing a null pointer is another typical cause of segmentation faults (besides accessing beyond array bounds).

You meant to use mpf_set_d, mpf_set_ui or mpf_set_si there (which one you use doesn't matter).


(1) I have copied the code from revision 2 and moved the two big arrays E and alpha to file scope to relieve the stack of that burden, after that and fixing three mpf_set(variable,0) on lines 94, 147 and 271, it ran to completion.

That doesn't necessarily mean the code is correct, at the end of the output I read

Successes=0 Failures=1
Success Rate=0.00000

which hints at a possible problem in the code logic, but I don't know what output to expect.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
  • Just wondering how did you know these were the issues?? I have tried to write the code all in GMP now and it is give me issues again, I want to be able to find them, but I don't know how, any help you could give me would be greatly appreciated. – adrem7 Apr 03 '13 at 13:33
  • Experience and debugging. When the debugger tells you that you got a segfault on line xyz, look closely at the line, most of the time, you can find the cause there. Look for the usual causes, out-of-bounds array accesses, null pointers, attempts to modify string literals, calls to the wrong functions (due to typos or confusion, many a coder called e.g. `strcpy` when really `strcmp` was intended). If you set the warning level to maximum, and let the compiler optimise (so it does some code flow analysis), it can even find a lot of problems before you run the code. – Daniel Fischer Apr 03 '13 at 13:43
  • Is there a way we could chat more privately if you would be so kind? – adrem7 Apr 03 '13 at 14:02