Segmentation fault. Core dumped

Pages: 12
This is a chunk of code that compiles but does not run.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  #include <math.h>
#include <fstream>      // std::ofstream
#include <complex>
#include <iostream>

typedef std::complex<double> dcomp;

  int main ()
{
  std::ofstream outFileInput;
  dcomp *Input, *ptr;
  dcomp valueC;
  ptr = Input;
  int N=1024;
  double xx,yy;
  outFileInput.open ("cppFFTinp.dat");
  for (int jj = 0; jj <= N-1; jj++)
    {
      valueC = dcomp (jj,0);
      if (jj != 0)
        ptr = ptr + 1;
      *ptr = valueC;
      yy = valueC.real();
      outFileInput << yy << std::endl;  // <== the program crushes at this statement.
    }


Everything works fine. I checked it with gdb step after step but the last statement crushes the program. I cannot understand why? It seems similar output statements worked before. What is wrong with this one? Any idea?

Thanks, - Alex
closed account (SECMoG1T)
Hi

1
2
3
  ptr = ptr + 1; ///ptr is a dangling pointer {points to no valid memory location} +1 leads
                       /// to access violation
      *ptr = valueC;///you are dereferencing a dangling pointer 
Last edited on
Andy, I am afraid you are wrong. Both statements work. I did the following: I commented out the last statement: outFileInput.... and ran a few rounds of the loop. Everything worked well. I was able to increment the pointer ptr, the presumed array Input filled with complex numbers, nothing was dangled. There was no crash. Once I uncomment the last statement the run failed.

Thanks, - Alex
Last edited on
closed account (SECMoG1T)
Am convinced am not wrong, thing is you should not rely on undefined behavior, using a point that points to no valid memory is undefined .. meaning that anything can happen,


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
std::ofstream outFileInput;
  dcomp *Input, *ptr;// this pointers have no valid addresses
  dcomp valueC;
  ptr = Input;     ///still no valid adresses
  int N=1024;
  double xx,yy;
  outFileInput.open ("cppFFTinp.dat");
  for (int jj = 0; jj <= N-1; jj++)
    {
      valueC = dcomp (jj,0);
      if (jj != 0)
        ptr = ptr + 1; ///you are using dangling pointer
      *ptr = valueC; /// derefencing a dangling pointer
      yy = valueC.real();
      outFileInput << yy << std::endl;  // <== the program crushes at this statement.
    }



a dangling pointer is a pointer that holds no valid memory and the side effects of using such pointers is undefined ;


1
2
3
4
5
6
7
8
9
10
11
///this are valid pointers shown here

 int *ptr;
 int value=0;
 ptr=&value;

 int *ptr2;
 ptr2=new int(10);

 int *dyn= new int[10];
dyn=dyn+1; ///is a valid operation 
line 13 - what's up with that?

Sorry alexBB, Andy is right.

You're using memory you don't own, and the behaviour is undefined. That means anything could happen, including nothing (as in your case), a crash, computer exploding, anything. You were probably (un)lucky enough that the address ptr pointed to was unused and accessible.

In any case it is unsafe in many ways. Think buffer overrun attacks, etc.

As it is you have an address in memory whose contents and type are unknown to you. What if that memory location holds valuable information? You may overwrite it.

You've got to consider the underlying concept though, a pointer holds a memory address. In your case, you're saying this address is the starting address of a dcomp object. When you increment the pointer, what you're saying is "I have a number of dcomp objects stored in memory, and I now want to move to the next one.

On my system, the program crashes straightaway at line 22, which is expected, because ptr was pointing right in the middle of a function (atexit), and of course it crashed.

You need to own the memory you're using. Try a standard container (vector) or use new/delete yourself, to get memory.

Instead of thinking "I removed a line and everything worked" consider "That line should work, what have I done prior to this to make it not work?"

Also, #include <cmath>
Thank you, tipaye and Andy as well. I cannot run the codes now I will do it in a few hours. Your comments of course are interesting, most likely valid but I want to mention one thing.

I tried vectors. They did not work for me. All my variables are complex numbers and the <vector> header has no mentioning of complex numbers at all, so I could not extract real part of a complex number when I needed to.

Also the whole idea of this code (which is a part of a larger program, sort of a simplified extract) is to use pointers to arrays *Input, *Output whose size will be determine at runtime. This is why I tried to avoid specifying array sizes.

Thanks for your pointers (metaphorical this time :-) again. I am a beginner with C++.

- Alex
Last edited on
I ran the code. I have to admit I was wrong and you are right. Now I have to modify it to make it work. Thank you much. - Alex
All my variables are complex numbers and the <vector> header has no mentioning of complex numbers

std::vector is a template. You can create a vector of any type. That is why there is no mention of complex in the vector header. The type of the vector is a parameter that you supply to the vector template.
1
2
  vector<int>  v_int;  // a vector of ints
  vector<dcomp> v_dcomp;  // a vector of your dcomp type 


AbstractionAnon, thanks, I will look into it. Now I have this question. I corrected the code and now everything works fine, however I am not happy with it. I debugged a similar program last week which also worked perfectly but it contained fixed input arrays , now I did it with pointers. I will tell you what my concern is. First I will try to explain what it is all about. I have written two variants of the main program for Fast Fourier Transfer subroutines written in c.

http://www.librow.com/articles/article-10

This is the second variant:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
 #include "fft_vect.h"
#include <math.h>
#include <cmath>
#include <fstream>      // std::ofstream
#include <complex>
#include <iostream>

const int MAX=1024;

typedef std::complex<double> dcomp;

  int main ()
{  
  std::ofstream outFileInput,outFileOutput;
  dcomp *Input, *Output;
  Input = new dcomp[MAX];
  Output = new dcomp[MAX];
  dcomp *ptr;
  dcomp valueC;
  ptr = Input;
  double xx;
  int N=256; 
  double blackmanHarrisWindow (int n, int N);
  outFileInput.open ("cppFFTinp.dat");
  outFileOutput.open("cppFFTout.dat");
  for (int jj = 0; jj <= MAX-1; jj++)
    {
      xx = blackmanHarrisWindow(jj,N);
      valueC = dcomp (xx,0);
      if (jj != 0)
        ptr = ptr + 1;   
      *ptr = valueC;
      outFileInput << valueC.real() << std::endl;
    }

  CFFT::Forward (Input,Output,N);
  CFFT::Inverse (Output,Input,N);

  for (int jj = 0; jj<MAX-1; jj++)
    {
      valueC = *(Input+jj);
      outFileOutput << valueC.real() << std::endl;
    }
}            // main

  double blackmanHarrisWindow (int n, int N)
    {
      double res,PI=3.141592653589793238462643383279502884197169;
      int N1;
      N1 = N-1;
      res = 0.35875-0.48829*cos(2.0*PI*n/N1)+0.14128*cos(4.0*PI*n/N1)+0.01168*cos(6.0*PI*n/N1);
      return res;
    } 


This is the previous variant:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 #include "fft.h"
#include <math.h>
#include <fstream>      // std::ofstream
#include <complex>
  
  int main ()
{  
  std::ofstream outFileInput,outFileOutput;
  complex Input[1024]=0, Output[1024]=0;
  complex valueC;
  int N=1024;
  double xx;  
  double blackmanHarrisWindow (int n, int N);
  outFileInput.open ("cppFFTinp.dat");
  outFileOutput.open("cppFFTout.dat");
  for (int jj = 0; jj<N-1; jj++)
    {
      xx = blackmanHarrisWindow(jj,N);
      valueC = complex(xx,0);
      Input[jj] = valueC;
      outFileInput << Input[jj].re() << std::endl;
    }
  CFFT::Forward (Input,Output,N);
  CFFT::Inverse (Output,Input,N);

  for (int jj = 0; jj<N-1; jj++)
    {
      valueC = Input[jj];
      xx = valueC.re();   
      outFileOutput << xx << std::endl;
    }
}            // main  


At the next step I am planning to convert the main program into a subroutine and call it from my major gfortran package. When fully implemented the FFT c part should be ready to work with variable input function lengths/variable arrays. I hoped to achieve it with pointers using the new operator as described here but it does not work this way. The FFT part works if the N integer is less than the size of the array but it fails if N is greater.

I am wondering if it is possible in principle to make this set of routines flexible in this sense: that it will reserve limited memory for Input and Output arrays and then expand it on demand? I think it is possible in C#.

AND WHAT IS THE SENSE OF USING POINTERS in my case?

Thanks, - Alex
You really should use vector<> instead. It will make this nearly trivial and it will fix a bug in your second variant: you're leaking the memory allocated at lines 16 and 17. Using your first version, as a guide, the code would look something like this (off the top of my head so it's likely full of bugs):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include "fft.h"
#include <math.h>
#include <fstream>      // std::ofstream
#include <complex>

void fft(int N)
{
    std::ofstream outFileInput,outFileOutput;
    vector<complex> Input(N), Output(N);
    complex valueC;
    double xx;  
    double blackmanHarrisWindow (int n, int N);
    outFileInput.open ("cppFFTinp.dat");
    outFileOutput.open("cppFFTout.dat");
    for (int jj = 0; jj<N-1; jj++) {
	xx = blackmanHarrisWindow(jj,N);
	valueC = complex(xx,0);
	Input[jj] = valueC;
	outFileInput << Input[jj].re() << '\n';
    }

    CFFT::Forward (&Input[0],&Output[0],N);
    CFFT::Inverse (&Output[0],&Input[0],N);

    for (int jj = 0; jj<N-1; jj++) {
	valueC = Input[jj];
	xx = valueC.re();   
	outFileOutput << xx << std::endl;
    }
}

int main()
{
    fft(1024);
}

dhayden, thank you very much. I hope it will work. I will report back in about 12 hours. - Alex
I have nothing to add but I'm curious about this:

double blackmanHarrisWindow

blackmanHarrisWindow what is this?
dhayden, this is your code with a minor addition:

1
2
3
4
5
6
7
8
9
10
11
12
13
 #include "fft.h"
#include <math.h>
#include <fstream>      
#include <complex>
#include <vector>

void fft(int N)
{
    std::ofstream outFileInput,outFileOutput;
    vector<complex> Input(N), Output(N);
    complex valueC;
    double xx;  
    double blackmanHarrisWindow (int n, int N);


and these the compilation errors:

1
2
3
4
5
6
7
8
9
 g++ fft_vec2.cpp
fft_vec2.cpp: In function ‘void fft(int)’:
fft_vec2.cpp:10:5: error: ‘vector’ was not declared in this scope
fft_vec2.cpp:10:5: note: suggested alternative:
/usr/include/c++/4.6/bits/stl_vector.h:180:11: note:   ‘std::vector’
fft_vec2.cpp:10:19: error: expected primary-expression before ‘>’ token
fft_vec2.cpp:10:28: error: ‘Input’ was not declared in this scope
fft_vec2.cpp:10:39: error: ‘Output’ was not declared in this scope
 


Line 10 is this:

vector<complex> Input(N), Output(N);
Last edited on
megatron, blackmanHarrisWIndow is a function. It is fully posted previously in this thread. You can see its graphic in Wikipedia.org article: "Window function." I use it for testing FFT routines as an input array. For some reason it looks much better (more interesting) when I compute it and gnuplott.
Last edited on
closed account (SECMoG1T)
std::vector<complex> Input(N), Output(N); is what you should use
well that balckmanwindow function looks weird too , how comes you declare it in main and your compiler just ignores that.
It is not balkmanwindow, it is blackmanHarrisWindow (int n, int N) function. There is nothing weird about it. As far as the vector declaration, I used what dhayden suggested.
closed account (SECMoG1T)


It's real weird believe me , I have never seen a function prototype within main and your compiler just assumed everything is ok , blackwindowharris must be from another galaxy am thinking ,hehe

used what dhayden suggested
@dhayden did suggest everything correctly but he must have forgotten to qualify the vector with it's namespace , what I did was just to qualify vector on his behave
std::vector
Last edited on
andy1992, you made me laugh. Anyhow, your suggestion to add std:: to the vector statement solved all problems. Now the code compiles and runs! Now I have three variants of my program. Thanks you very much.

Please explain to me the advantage of using vector class. I suspect it allows me to use dynamic memory allocation, correct?

Thanks,- Alex
closed account (SECMoG1T)
It did compiler are you sure? you must be in big trouble ,your compiler doesn't seem to be very friendly I guess if that black function is still in main, thing is how will the os be able to allocate a stack for a function within another function stack ??? But just forget it anyway.

About vectors: they are standard containers whose implimentation allows an efficient management of dynamic memory, they got take care of all bugs associated with dynamic memory. .. mem leaks, ... and many more, for example if you decide to use manually allocated arrays , you will have to take care of allocation, reallocations, dellocations ... name them, all those stuff are taken care of in vectors.
Last edited on
I don't understand your concern about the blackmanHarrisWindow. The body of the function is outside main. But without that declaration I was getting a compile error because the compiler needs to know the type of the function output.

I appreciate your explanation for the vector class advantage. This is what I suspected, in fact. I've read it somewhere, don't recall now where though.
Pages: 12