LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices



Reply
 
Search this Thread
Old 07-13-2005, 02:32 PM   #1
Yerp
Member
 
Registered: Jun 2004
Distribution: Turtle Kevux 0.8.8
Posts: 129

Rep: Reputation: 15
Question Why does this code segfault?


Code:
#include <unistd.h>

typedef struct{
  int a;
  int b;
} TEST;

int main(){
  TEST First;
  TEST *Second;
  
  First.a = 0;
  First.b = 0;
  sleep(2);      /* segfaults after sleep */
  Second->a = 0;
  Second->b = 0;
  
  return 0;
}
This is beyond me.. I look over the code over and over again, and can't find what is wrong!

Tried both gcc & g++, identical results.

Compiler -> gcc-3.3.6
glibc -> 2.3.4
kernel -> 2.6.11.12

ldd a.out returns:
linux-gate.so.1 => (0xffffe000)
libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x40019000)
libm.so.6 => /lib/libm.so.6 (0x400d3000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x400f6000)
libc.so.6 => /lib/libc.so.6 (0x400fe000)
/lib/ld-linux.so.2 (0x40000000)
 
Old 07-13-2005, 02:46 PM   #2
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
You never allocate memory for Second. If you want it to point to the memory allocated on the stack for First, initialize it like so:

TEST* Second = &First;

If you want to have it point to it's very own memory on the heap, allocate memory for it like so:

TEST* Second = new TEST;

// Then when done using it free the memory with

delete Second;

Last edited by deiussum; 07-13-2005 at 02:47 PM.
 
Old 07-13-2005, 03:11 PM   #3
paulsm4
Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Hi -

deiussum - is correct: your program is crashing because you're doing an assignment using a pointer variable ("Second") that was never initialized.

You would have spotted the problem immediately had you tried running your program inside a debugger (for example, "gdb").

The debugger is your friend: please consider familiarizing yourself with one of the many debuggers out there (this is heresy in a Linux forum, but I'd recommend starting with Visual Studio to familiarize yourself with debuggers in general...)
 
Old 07-13-2005, 03:23 PM   #4
sundialsvcs
Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 5,455

Rep: Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172
Just to clarify... the construct
Code:
TEST *Second
means that Second is a pointer to a TEST, which you have defined as a structure.

In other words, Second is a simple integer-like variable, currently unitialized, whose value will be understood to be the address of a TEST.

The value of Second is undefined ... it is garbage ... and fortunately for you it points to a "bogus" memory address, resulting in the segmentation-fault. What you must do, with any pointer-type variable is:
  • Always ensure that the pointer is properly initialized before you use it. You should know at all times that any pointer either points to a valid object or it is known to be NULL. ("NULL" is a special value that "points to nothing.")
  • When you allocate an object, you must always free that object.
  • When you do free the object, I strongly recommend that you set the pointer back to NULL. This preserves the you-enforced rule that "the value in the pointer must be valid or it must be NULL." Even if some would argue that it's unnecessary or "inefficient," I assure you that the discipline will serve you well.
 
Old 07-13-2005, 04:21 PM   #5
paulsm4
Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
And bear in mind:

1. If you do a "malloc()", you need to do a corresponding "free()".

2. If you do a "new", then you need to do a corresponding "delete".

3. "malloc()/free()" and "new/delete" are *different things", you *cannot* mix'n'match them.
Malloc and free are C library functions; they can be called from C, C++ (or any other language that can interface to the standard library).
"New" and "delete" are C++ operators; they can be used *only* in a C++ program.
 
Old 07-14-2005, 10:21 AM   #6
hk_linux
Member
 
Registered: Nov 2004
Location: India
Distribution: RedHat, PCQLinux, Fedora
Posts: 95

Rep: Reputation: 15
Quote:
* When you do free the object, I strongly recommend that you set the pointer back to NULL. This preserves the you-enforced rule that "the value in the pointer must be valid or it must be NULL." Even if some would argue that it's unnecessary or "inefficient," I assure you that the discipline will serve you well.
I was using the same style in C. I wish to recollect an incident in the recent past.

My code looked something like this.

Code:
int *a;
a= malloc (10);

blah..blah....

free (a);
a=NULL;

blah.. blah....

free (a);
As you see, the pointer was freed two times, but since the ptr was re-init to NULL, the second free didnot
have any effect. If it was not re-initialized, segmentation violation would have occured.
Then the problem (second freeing) would have been found out and fixed.

Now my question is, is it OK to re-initialize a pointer to NULL, because it can supress the problems like the one
i mentioned above. Does it not result in an unclean code (working one though).........

What are your comments?
 
Old 07-14-2005, 11:13 AM   #7
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
One good reason for initializing to NULL after freeing memory is that it makes it easy to test if the pointer is valid. If you leave a dangling pointer, there is no easy way to know that it is dangling until you use it and it causes problems.

Last edited by deiussum; 07-14-2005 at 11:15 AM.
 
Old 07-14-2005, 11:14 AM   #8
paulsm4
Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
I think sundialsvcs advice is good advice. Any "habit" that forces you to *think*; any "convention" that takes the implicit ("a freed pointer has become undefined") and makes it *explicit* ("a null pointer cannot be used") - is definitely a Good Thing.

I think opening *any* door to *any* potential bugs is a Bad Thing.

I would suggest that sundialsvcs's advice is a good way to minimize the chances of accidentally using a freed (or uninitialized) pointer (like Yerp inadvertantly did).

I would further suggest that sundialsvcs's advice is *also* applicable to the *second* kind of bug that hk suggested. If the pointer is always NULL whenever the pointer variable is undefined, then you can easily prevent double-freeing with the following:

Code:
  if (mypointer!=NULL)
    free mypointer;
You'll notice that this *prevents* the bug; it doesn't just "detect" it (said detection being a program crash and a core dump). In my book, "prevention" trumps "detection" every time.

IMHO .. Paul Santa Maria

PS:
"deiussum" and I were typing in essentially the same answer together at the same time. We both seem to be in agreement with sundialsvcs :-)

Last edited by paulsm4; 07-14-2005 at 11:19 AM.
 
Old 07-14-2005, 11:34 AM   #9
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
Also, with hk's problem, setting it to NULL isn't necessarily what hid the problem. Just as a quick test I wrote the following C program:

Code:
#include <stdlib.h>

int main()
{
    int *p = malloc(sizeof(int));

    free(p);
    p = NULL;
    free(p);

    return 0;
}
Compiled it, ran it, no crash.
Commented out the p = NULL;
Compiled it, ran it, no crash...
 
Old 07-14-2005, 12:26 PM   #10
Yerp
Member
 
Registered: Jun 2004
Distribution: Turtle Kevux 0.8.8
Posts: 129

Original Poster
Rep: Reputation: 15
thanx, now I realise what I was thinking.

I had the char *C; notation in my mind, and used them as the same...despite my experience with malloc, calloc, realloc, new, delete, etc...
apparently this is what happens when I don't program for over 6-months and come back to it
 
Old 07-15-2005, 12:22 AM   #11
hk_linux
Member
 
Registered: Nov 2004
Location: India
Distribution: RedHat, PCQLinux, Fedora
Posts: 95

Rep: Reputation: 15
hi deiussum,
Thats weird. I copied ur program and executed. It dumped core for me.....

Quote:
Extract from man free

free() frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behaviour occurs. If ptr is NULL, no operation is performed.
Undefined behavior..
 
Old 07-15-2005, 04:38 PM   #12
Quigi
Member
 
Registered: Mar 2003
Location: Cambridge, MA, USA
Distribution: Ubuntu (Dapper and Heron)
Posts: 377

Rep: Reputation: 31
Yes "undefined behavior" -- that seems to be the point of replies to your first message in this thread.

If you free twice, it may crash right there. Or it may run "fine". Or it may subly corrupt dynamic memory management ("the heap"), with consequences that manifest ten million instructions later. Or not, until you install your software at a customer's

BTW, to track down dynamic memory problems, I found Valgrind extremely helpful.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
User Preferences: Use HTML code instead of vB code? (vB code is overrated) stefanlasiewski LQ Suggestions & Feedback 5 07-26-2005 02:37 AM
grep, ln both segfault TexasDex Linux - Software 1 03-20-2005 06:46 PM
segfault prob in C zaichik Programming 5 01-25-2005 08:00 AM
segfault with fglrx Vyeperman Linux - Hardware 0 04-18-2004 12:06 AM
Evolution SegFault granitepoint Linux - Software 0 01-12-2003 12:11 AM


All times are GMT -5. The time now is 11:10 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration