MHB Solve Segmentation Fault: Destroy Planetary System "Solid

  • Thread starter Thread starter mathmari
  • Start date Start date
  • Tags Tags
    Fault
Click For Summary
The discussion revolves around troubleshooting a segmentation fault in a C function designed to destroy a planetary system and manage asteroids. The key issue arises when accessing the `ffplan` array, where the index `j` may be out of range, leading to the segmentation fault. Participants suggest using assertions to verify that all indices are valid and recommend using a debugger like gdb to trace the program's execution for better insight into the error. The importance of correctly using the `exit` function is emphasized, as failing to include parentheses can cause the program to continue running unexpectedly. Overall, the conversation highlights debugging strategies and the need for careful index management in linked data structures.
  • #91
mathmari said:
(Malthe)

Yes, I want to iterate over the linked list and print some information.
How can I do it then, without using the head?? (Wondering)

Copy the [m]asteroids[/m] data member to a local pointer and use that to iterate. (Mmm)

Also, I suggest to use recognizable names for pointers to important data structures.
It's better to use a name like [m]p[/m] only for iterating over a collection. (Nerd)

So I suggest something like:
Code:
plansys_t *planetarySystem = StarS[k].plasy;
...
asteroid_t *q = planetarySystem ->asteroids;
while (q != NULL) {
    ...
    q = q->next;
}
(Wasntme)
 
Technology news on Phys.org
  • #92
I like Serena said:
Copy the [m]asteroids[/m] data member to a local pointer and use that to iterate. (Mmm)

Also, I suggest to use recognizable names for pointers to important data structures.
It's better to use a name like [m]p[/m] only for iterating over a collection. (Nerd)

So I suggest something like:
Code:
plansys_t *planetarySystem = StarS[k].plasy;
...
asteroid_t *q = planetarySystem ->asteroids;
while (q != NULL) {
    ...
    q = q->next;
}
(Wasntme)

Ok! Now it isn't [m]NULL[/m] after the while-loop!

Now I get the following:

[m]...
Program received signal SIGSEGV, Segmentation fault.
0x00402593 in destruction (solid=7620203, gap=5000) at stars.c:342
342 DELETE(f->prev, f->prev->as);[/m]

Why do we get a segmentation fault at this point??

Code:
while(sum<gap){
		sum=sum+f->gap;
		f=f->next;
		DELETE(f->prev, f->prev->as);
	}

(Wondering)

The DELETE() function is the following:

Code:
void DELETE(asteroid_t *pointer, int x){
	while(pointer != NULL && pointer->as != x) {
		pointer=pointer->next;
        }
	if(pointer == NULL) {
		printf("Element %d is not present in the list\n", x);
		return;
        } 
	if(pointer->next != NULL){
		pointer->next->prev=pointer->prev;
	}
	if(pointer->prev != NULL){
		pointer->prev->next = pointer->next;
	}
        free(pointer);
}
 
  • #93
mathmari said:
Ok! Now it isn't [m]NULL[/m] after the while-loop!

Good! (Emo)

Why do we get a segmentation fault at this point??

Code:
1. while(sum<gap){
2. 		sum=sum+f->gap;
3. 		f=f->next;
4. 		DELETE(f->prev, f->prev->as);
5. }

(Wondering)

You'll get a segmentation fault if you try to dereference a pointer, when it does not point to a valid location. Typically because it is NULL. (Nerd)

So... how do you know in line 2 and 3 that [m]f[/m] is not a NULL pointer? (Wondering)

And how do you know in line 4, after [m]f=f->next[/m], that [m]f[/m] is not a NULL pointer? (Wondering)
 
  • #94
I like Serena said:
You'll get a segmentation fault if you try to dereference a pointer, when it does not point to a valid location. Typically because it is NULL. (Nerd)

So... how do you know in line 2 and 3 that [m]f[/m] is not a NULL pointer? (Wondering)

And how do you know in line 4, after [m]f=f->next[/m], that [m]f[/m] is not a NULL pointer? (Wondering)

Can we write it as followed??

Code:
while(sum<gap && f->next != NULL){
		sum=sum+f->gap;
		f=f->next;
		DELETE(f->prev, f->prev->as);
}
if(f != NULL){
		DELETE(f, f->as);
}

(Wondering)
 
  • #95
mathmari said:
Can we write it as followed??

Code:
while(sum<gap && f->next != NULL) {
		sum=sum+f->gap;
		f=f->next;
		DELETE(f->prev, f->prev->as);
}
if(f != NULL){
		DELETE(f, f->as);
}

(Wondering)

I consider this suspect code, since we're deleting elements from a list while iterating over it. Moreover the deletion function will iterate on its own. (Thinking)
Furthermore, the special cases where we're deleting the first respectively last element of the list does not appear to be properly accounted for. That appears to be the reason for a segmentation violation. (Worried)

Do you want to delete elements from the list as long as the sum of gaps is less than the given gap? And do you want to start from the beginning of the list? (Wondering)

If so, then I suggest something like:
Code:
sum = 0;
f = head;
while(sum<gap && f != NULL){
    sum=sum+f->gap;
    next=f->next;
    free(f);    
    f = next;
}
head = f;
if (f != NULL) {
    f->prev = NULL;
}
(Wasntme)
 
  • #96
I like Serena said:
Do you want to delete elements from the list as long as the sum of gaps is less than the given gap? And do you want to start from the beginning of the list? (Wondering)

Yes... (Nod)

I like Serena said:
If so, then I suggest something like:
Code:
sum = 0;
f = head;
while(sum<gap && f != NULL){
    sum=sum+f->gap;
    next=f->next;
    free(f);    
    f = next;
}
head = f;
if (f != NULL) {
    f->prev = NULL;
}
(Wasntme)

What is [m]head[/m]?? Is it maybe [m]p->asteroids[/m] ?? (Wondering)

Also what does the command [m]next=f->next;[/m] mean?? (Wondering)
 
  • #97
mathmari said:
What is [m]head[/m]?? Is it maybe [m]p->asteroids[/m] ?? (Wondering)

I don't know. You left out the context.
It's the pointer to the beginning of the list. (Dull)

Btw, is there also a Sentinel? (Wondering)
If so that also needs to be updated.
Also what does the command [m]next=f->next;[/m] mean?? (Wondering)

It means we save [m]f->next[/m] in an extra temporary variable (named [m]next[/m]), so that we still know what it is after we have freed [m]f[/m]. (Nerd)
Otherwise we might get a segmentation violation and we don't want that do we? (Devil)
 
  • #98
I like Serena said:
I don't know. You left out the context.
It's the pointer to the beginning of the list. (Dull)
I have to write a function for the destruction of the planetary system "solid".
With the destruction of the planetary system, the asteroids where the gap between this one and the object, is at least "gap" will also be destructed. (so, they have to be deleted) The asteroids for which the gap is greater are converted to free-floating planets consisting a new collection of free-floating planets (ffplan_t). This new collection should be added to the array of the free-floating planets of the star system to which the planetary system, that is destructed, belonged. The identifier "fp" of the new collection is the identifier of the planetary system that is destructed. The list of the free-floating planets that corresponds to the new collection should be sorted as for the field "as" of the asteroids that are contained. The destructed planetary system should be deleted from the list of planetary systems of the star system to which it belonged.

The function I have written is the following:

Code:
int destruction(int solid, int gap){
	int ffplanpos=-1;
	int i, j=-1;
	int sum=0;
	asteroid_t *planf = calloc(1, sizeof(asteroid_t));
	asteroid_t *f=NULL;
	plansys_t *p=NULL;
	asteroid_t *next=NULL;
	for(i=0; i<Sfreep; i++){
		p=StarS[i].plasy;
		while (p != NULL && p->solid != solid){
			p=p->next;
		}
		if(p != NULL && p->solid == solid){
			j=i;
		}
	}
	
	if(j == -1){
		return -1;
	}
	
	p=StarS[j].plasy;
	
	
	if(p == NULL){
		printf("The planetary system with identifier %d couldn't be found\n", solid);
		return -1;
	}
	
	if(p->asteroids == NULL){
		printf("The planetary system doesn't contain any asteroids\n");
		return -1;
	}
	
	
	f=p->asteroids;
	
	while(sum<gap && f != NULL){
    	sum=sum+f->gap;
    	next=f->next;
    	free(f);    
    	f = next;
	}
	p->asteroids = f;
	if (f != NULL) {
    	f->prev=NULL;
	}

	i=0;
	while(i<max && StarS[j].ffplan[i].fp != INT_MAX){
		i=i+1;
	}

	ffplanpos=i;
	

	if(ffplanpos == -1){
		return -1;
	}
	
	StarS[j].ffplan[ffplanpos].fp=solid;
	
	
	planf->as=f->as;
	planf->gap=0;
	planf->next=NULL;
	planf->prev=NULL;	f=f->next;
	while(f != NULL){
		if (StarS[j].ffplan[ffplanpos].ff == NULL) {
        	StarS[j].ffplan[ffplanpos].ff = planf;
        } else {
        	asteroid_t *last = StarS[j].ffplan[ffplanpos].ff;
        	while (last->next != NULL) {
        		last = last->next;
        	}
        	last->next = planf;
       	}     
		f=f->next;
	}     
	
	
	printf("\n\nPlanet Systems = ");
	
	while(StarS[j].plasy != NULL){
		printf(" %d ", StarS[j].plasy->solid);
		StarS[j].plasy=StarS[j].plasy->next;
	}
	
	printf("\n\nFree-floatingM = ");
	
	for(i=0; i<ffplanpos; i++){
		printf(" %d ", StarS[j].ffplan[i].fp);
	}
	
	printf("\n\nFree-floating planets = ");

	
	for(i=0; i<=ffplanpos; i++){
		while(StarS[j].ffplan[i].ff != NULL){
			printf(" %d ", StarS[j].ffplan[i].ff->as);
			StarS[j].ffplan[i].ff=StarS[j].ffplan[i].ff->next;
		}
	}

	return 0;
	
}
I like Serena said:
Btw, is there also a Sentinel? (Wondering)
If so that also needs to be updated.

There is no Sentinel in this list.
I like Serena said:
It means we save [m]f->next[/m] in an extra temporary variable (named [m]next[/m]), so that we still know what it is after we have freed [m]f[/m]. (Nerd)
Otherwise we might get a segmentation violation and we don't want that do we? (Devil)

Ahaa.. Ok! (Malthe)
 
  • #99
mathmari said:
The function I have written is the following:

There is no Sentinel in this list.

Ahaa.. Ok! (Malthe)

I see you have updated your program.
So what is it doing now? (Wondering)
Does it still give you a segmentation violation? (Sweating)
 
  • #100
I like Serena said:
I see you have updated your program.
So what is it doing now? (Wondering)
Does it still give you a segmentation violation? (Sweating)

Now I get the following:

[m]Program received signal SIGSEGV, Segmentation fault.
0x0040260c in destruction (solid=7620203, gap=5000) at stars.c:363
363 planf->as=f->as;[/m]

(Wondering)
 
  • #101
mathmari said:
Now I get the following:

[m]Program received signal SIGSEGV, Segmentation fault.
0x0040260c in destruction (solid=7620203, gap=5000) at stars.c:363
363 planf->as=f->as;[/m]

(Wondering)

Does that mean we've progressed again? (Wondering)

From [m]gdb[/m] you can get some more information by typing:

[m](gdb) p f[/m]

This will print the value of [m]f[/m].
It it is NULL that would confirm that [m]f[/m] is the problem.
Otherwise [m]planf[/m] might be the problem. (Nerd)
 
  • #102
I like Serena said:
Does that mean we've progressed again? (Wondering)

From [m]gdb[/m] you can get some more information by typing:

[m](gdb) p f[/m]

This will print the value of [m]f[/m].
It it is NULL that would confirm that [m]f[/m] is the problem.
Otherwise [m]planf[/m] might be the problem. (Nerd)

When I write [m](gdb p f[/m] I get the following:

[m]$1 = (planet_t *) 0x0[/m]

But why is it [m]NULL[/m] ?? (Wondering)
 
  • #103
mathmari said:
When I write [m](gdb) p f[/m] I get the following:

[m]$1 = (planet_t *) 0x0[/m]

But why is it [m]NULL[/m] ?? (Wondering)

How does [m]f[/m] get its value before the problematic line of code? (Wondering)
 
  • #104
I like Serena said:
How does [m]f[/m] get its value before the problematic line of code? (Wondering)

It is a pointer to the list [m]f=p->asteroids;[/m].
 
  • #105
mathmari said:
It is a pointer to the list [m]f=p->asteroids;[/m].

Then that list is empty for some reason. (Thinking)
 
  • #106
I like Serena said:
Then that list is empty for some reason. (Thinking)

But if this list were also [m]NULL[/m], wouldn't we have to get the following:
[m]The planetary system doesn't contain any asteroids[/m] ?? (Wondering)
Code:
if(p->asteroids == NULL){
		printf("The planetary system doesn't contain any asteroids\n");
		return -1;
	}
 
  • #107
mathmari said:
But if this list were also [m]NULL[/m], wouldn't we have to get the following:
[m]The planetary system doesn't contain any asteroids[/m] ?? (Wondering)
Code:
if(p->asteroids == NULL){
		printf("The planetary system doesn't contain any asteroids\n");
		return -1;
	}

Then the value of [m]p->asteroids[/m] must have changed after that if-statement. (Sweating)
What happened to it? (Wondering)
 
  • #108
I like Serena said:
Then the value of [m]p->asteroids[/m] must have changed after that if-statement. (Sweating)
What happened to it? (Wondering)

But direct after the if-statement we set it to [m]f[/m].

Code:
if(p->asteroids == NULL){
		printf("The planetary system doesn't contain any asteroids\n");
		return -1;
	}
	
	
	f=p->asteroids;

(Wondering)
 
  • #109
mathmari said:
But direct after the if-statement we set it to [m]f[/m].

Code:
if(p->asteroids == NULL){
		printf("The planetary system doesn't contain any asteroids\n");
		return -1;
	}
	
	
	f=p->asteroids;

(Wondering)

And what happens afterwards with [m]f[/m]? (Thinking)
 
  • #110
I like Serena said:
And what happens afterwards with [m]f[/m]? (Thinking)

After that we delete elements from the list as long as the sum of gaps is less than the given gap.

Code:
while(sum<gap && f != NULL){
    	sum=sum+f->gap;
    	next=f->next;
    	free(f);    
    	f = next;
}
p->asteroids = f;
if (f != NULL) {
        f->prev=NULL;
}
 
  • #111
mathmari said:
After that we delete elements from the list as long as the sum of gaps is less than the given gap.

Code:
while(sum<gap && f != NULL){
    	sum=sum+f->gap;
    	next=f->next;
    	free(f);    
    	f = next;
}
p->asteroids = f;
if (f != NULL) {
        f->prev=NULL;
}

I see... (Thinking)

So afterwards f points to the remainder of the list... which might be empty! :eek:
 
  • #112
I like Serena said:
I see... (Thinking)

So afterwards f points to the remainder of the list... which might be empty! :eek:

So, can we do it as followed??

Code:
int destruction(int solid, int gap){
	int ffplanpos=-1;
	int i, j=-1;
	int sum=0;
	asteroid_t *planf = calloc(1, sizeof(asteroid_t));
	asteroid_t *f=NULL;
	plansys_t *p=NULL;
	asteroid_t *next=NULL;
	for(i=0; i<Sfreep; i++){
		p=StarS[i].plasy;
		while (p != NULL && p->solid != solid){
			p=p->next;
		}
		if(p != NULL && p->solid == solid){
			j=i;
		}
	}
	
	if(j == -1){
		return -1;
	}
	
	p=StarS[j].plasy;
	
	
	if(p == NULL){
		printf("The planetary system with identifier %d couldn't be found\n", solid);
		return -1;
	}
	
	if(p->asteroids == NULL){
		printf("The planetary system doesn't contain any asteroids\n");
		return -1;
	}
	
	
	f=p->asteroids;
	
	while(sum<gap && f != NULL){
    	        sum=sum+f->gap;
    	        next=f->next;
    	        free(f);    
    	        f = next;
	}
	p->asteroids = f;
	if (f != NULL) {
    	        f->prev=NULL;
	}

	i=0;
	while(i<max && StarS[j].ffplan[i].fp != INT_MAX){
		i=i+1;
	}

	ffplanpos=i;
	

	if(ffplanpos == -1){
		return -1;
	}
	
	StarS[j].ffplan[ffplanpos].fp=solid;
	
	if(f != NULL){
	       planf->as=f->as;
	       planf->gap=0;
	       planf->next=NULL;
	       planf->prev=NULL;	       f=f->next;
	       while(f != NULL){
		       if (StarS[j].ffplan[ffplanpos].ff == NULL) {
        	                StarS[j].ffplan[ffplanpos].ff = planf;
                       } else {
        	                 asteroid_t *last = StarS[j].ffplan[ffplanpos].ff;
        	                 while (last->next != NULL) {
        		                   last = last->next;
        	                 }
        	                 last->next = planf;
       	               }     
		       f=f->next;
	      }     
	
      }	

        printf("\n\nPlanet Systems = ");
	
	while(StarS[j].plasy != NULL){
		printf(" %d ", StarS[j].plasy->solid);
		StarS[j].plasy=StarS[j].plasy->next;
	}
	
	printf("\n\nFree-floatingM = ");
	
	for(i=0; i<ffplanpos; i++){
		printf(" %d ", StarS[j].ffplan[i].fp);
	}
	
	printf("\n\nFree-floating planets = ");

	
	for(i=0; i<=ffplanpos; i++){
		while(StarS[j].ffplan[i].ff != NULL){
			printf(" %d ", StarS[j].ffplan[i].ff->as);
			StarS[j].ffplan[i].ff=StarS[j].ffplan[i].ff->next;
		}
	}

	return 0;
	
}

(Wondering)
 
  • #113
mathmari said:
So, can we do it as followed?? (Wondering)

I think that would take care of the segmentation fault yes. (Smile)

How about the program logic?
Does it still do what it is supposed to do? (Wondering)
 
  • #114
I like Serena said:
I think that would take care of the segmentation fault yes. (Smile)

(Smile)
I like Serena said:
How about the program logic?
Does it still do what it is supposed to do? (Wondering)

I don't know because it prints the following:

[m]Planet Systems = 7620213 7620203
Free-floatingM = 7620203
Free-floating planets =[/m]

It doesn't print anything at Free-floating planets, because [m]f[/m] is [m]NULL[/m], right?? (Wondering)

But having the following in the file.txt

[m]I
C 762
B 7620213 762
B 7620203 762
A 987 4232 7620203
A 985 1232 7620203
A 986 6344 7620203
D 7620203 5000[/m]

we have created three asteroids with gaps 4232, 1232, 6344.

So, should the last asteroid get a free-floating planet, since with [m]D 7620203 5000[/m] we want to convert these asteroids into free-floating planets that have gap greater than 5000, or not?? (Wondering)
 
  • #115
mathmari said:
So, should the last asteroid get a free-floating planet, since with [m]D 7620203 5000[/m] we want to convert these asteroids into free-floating planets that have gap greater than 5000, or not?? (Wondering)

Or have I understood it wrong?? (Wondering)
 
  • #116
mathmari said:
we have created three asteroids with gaps 4232, 1232, 6344.

So, should the last asteroid get a free-floating planet, since with [m]D 7620203 5000[/m] we want to convert these asteroids into free-floating planets that have gap greater than 5000, or not?? (Wondering)

I think you are right.
So it seems something is still going wrong with the destruction of the asteriods - it appears one too many is destroyed. (Sweating)
 
  • #117
I like Serena said:
So it seems something is still going wrong with the destruction of the asteriods - it appears one too many is destroyed. (Sweating)

But why does this occur?? (Wondering)
 
  • #118
mathmari said:
But why does this occur?? (Wondering)

We should zoom in on the code that decides which ones to destroy! (Nod)
What is the code? (Wondering)
And what should it do? (Wondering)
 
  • #119
I like Serena said:
We should zoom in on the code that decides which ones to destroy! (Nod)
What is the code? (Wondering)
And what should it do? (Wondering)

Code:
	f=p->asteroids;
	
	while(sum<gap && f != NULL){
    	sum=sum+f->gap;
    	next=f->next;
    	free(f);    
    	f = next;
	}
	p->asteroids = f;
	if (f != NULL) {
    	f->prev=NULL;
	}

	i=0;
	while(i<max && StarS[j].ffplan[i].fp != INT_MAX){
		i=i+1;
	}

	ffplanpos=i;
	

	if(ffplanpos == -1){
		return -1;
	}
	
	StarS[j].ffplan[ffplanpos].fp=solid;
	
	if(f != NULL){
	planf->as=f->as;
	planf->gap=0;
	planf->next=NULL;
	planf->prev=NULL;	f=f->next;
	while(f != NULL){
		if (StarS[j].ffplan[ffplanpos].ff == NULL) {
        	StarS[j].ffplan[ffplanpos].ff = planf;
        } else {
        	asteroid_t *last = StarS[j].ffplan[ffplanpos].ff;
        	while (last->next != NULL) {
        		last = last->next;
        	}
        	last->next = planf;
       	}     
		f=f->next;
	}     
	
}

I made some changes:

Code:
	f=p->asteroids;
	sum=f->gap;
	while(sum<gap && f != NULL){
    	       next=f->next;
    	       free(f);    
    	       f = next;
               sum=sum+f->gap;
	}
	p->asteroids = f;
	if (f != NULL) {
    	       f->prev=NULL;
	}

	i=0;
	while(i<max && StarS[j].ffplan[i].fp != INT_MAX){
		i=i+1;
	}

	ffplanpos=i;
	

	if(ffplanpos == -1){
		return -1;
	}
	
	StarS[j].ffplan[ffplanpos].fp=solid;
	
	if(f != NULL){
	        planf->as=f->as;
	        planf->gap=0;
	        planf->next=NULL;
	        planf->prev=NULL;

	        while(f != NULL){
		     if (StarS[j].ffplan[ffplanpos].ff == NULL) {
        	               StarS[j].ffplan[ffplanpos].ff = planf;
                  } else {
        	       asteroid_t *last = StarS[j].ffplan[ffplanpos].ff;
        	       while (last->next != NULL) {
        		       last = last->next;
        	        }
        	        last->next = planf;
       	        }     
		f=f->next;
	}     
	
}
Now it prints the following:
[m]Planet Systems = 7620203 7620213
Free-floatingM = 7620203
Free-floating planets = 986[/m]

So, is it correct now?? (Wondering)
 
  • #120
Or is still something wrong?? (Wondering)
 

Similar threads

Replies
2
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 20 ·
Replies
20
Views
5K
  • · Replies 5 ·
Replies
5
Views
4K