Segmentation fault when calling function

Sep 10, 2010 at 10:19pm
Hello

I had a problem with calling a function ... (it's working now, but I'd like to know why ;-) )

my code is like this:

MyClass c = get_my_class(some_val);
call_function(c);

void call_function(MyClass c)
{
c.do_something...
}

I get a Segmentation fault when calling the function like this ...

but when I do it like this:

call_function(get_my_class(some_val));

there is no Segmentation fault ...

can anyone tell me why this can happen ...

mfg
ps
Sep 10, 2010 at 10:38pm
It's probably that your class has no default constructor, and when you call call_function(), the compiler is not doing a good job of guessing at how to construct your class. Try passing a reference like this:

void call_function MyClass& C )
{
c.do_something();
}

(Notice the ampersand?)

Good luck!
Sep 10, 2010 at 11:26pm
right ... I already figured that possiblity out ... :-)

2 further questions:
1) why the & (I know it helps and roughly what it does but why can the Segmentation fault be avoided)?
2) where in my code is the default constructor relevant (I don't exactly know what you mean) ... get_my_class(some_val) - is working out all right as:

MyClass c = get_my_class(some_val);
c.do_something...

is working ...

best
ps
Sep 11, 2010 at 12:08am
You'd only get a segmentation fault if your copy ctor or assignment operator are no good.

If you don't provide your own, the compiler will fill in its own implementations, which work fine for most classes, but have issues when you have dynamically allocated memory in the class.

Here's an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class A
{
  int* p;

public:
  A()
  {
    p = new int;
  }

  ~A()
  {
    delete p;
  }

  void Set(int set)
  {
    *p = set;
  }
};


Seems harmless, right? But it's wrong!

For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void foo()
{
A a;  // this allocates an int for 'a.p'

{
  A b(a);  // this copies 'a' to another A object, 'b'

  // note that b did not allocate it's own 'p'
  //  b.p was just assigned to a.p.  as if you did this:
  //   b.p = a.p;
  //
  //  because of this, both objects point to the same memory

} // here, b's destructor deletes 'p'
  // which is bad because a was still using it!

a.Set(5);  // HEAP CORRUPTION!!!
   // a.p has already been deleted by b's destructor, so calling set here is bad

} // EXPLODE
  // a's dtor is being called, which deletes p AGAIN (after b's dtor deleted it)
  // this may cause a segfault (if you're lucky) 


When you pass objects to functions by value (without the & operator), you are creating copies, which causes the above problem.


The solution here is to write your own copy constructor and assignment operator which correctly copies the object:

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
class A
{
  int* p;

public:
  A()
  {
    p = new int;
  }

  // FIX:  Write your own copy ctor
  A(const A& a)
  {
    p = new int( *(a.p) );
  }

  // FIX:  and assignment operator
  A& operator = (const A& a)
  {
    *p = *(a.p);
    return *this;
  }

  ~A()
  {
    delete p;
  }

  void Set(int set)
  {
    *p = set;
  }
};
Sep 11, 2010 at 12:44am
hello

ok - on the first look this seems to be my problem ... as it's quite late - I'll have a look at it tomorrow ;-)

thanks for the answers!

ps
Sep 11, 2010 at 12:45am
Disch wrote:
} // EXPLODE
Thanks for this, it gave me a real laugh :D
Topic archived. No new replies allowed.