MHB Solve Segmentation Fault: Destroy Planetary System "Solid

  • Thread starter Thread starter mathmari
  • Start date Start date
  • Tags Tags
    Fault
AI Thread 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.
  • #51
mathmari said:
When I write the command [m]gdb a.out[/m] I get:

[m]a.out: No such file or directory.[/m]

(Wondering)

How do you normally run your executable? (Wondering)
 
Technology news on Phys.org
  • #52
Try "gdb ./a.out". Note the period before "/".
 
  • #53
I wrote [m]gdb a.exe[/m].

Then I wrote the command [m](gdb) r[/m] and I get the following:

[m]Starting program: /cygdrive/c/cygwin/a.exe
[New thread 3764.0x50c]
Error: dll starting at 0x76c60000 not found.
Error: dll starting at 0x75c30000 not found.
Error: dll starting at 0x76c60000 not found.
Error: dll starting at 0x76b60000 not found.
[New thread 3764.0x4c4]
Usage: /a <input_file>

Program exited with code 01.[/m]

What does this mean?? (Wondering)
 
  • #54
mathmari said:
I wrote [m]gdb a.exe[/m].

Then I wrote the command [m](gdb) r[/m] and I get the following:

[m]Starting program: /cygdrive/c/cygwin/a.exe
[New thread 3764.0x50c]
Error: dll starting at 0x76c60000 not found.
Error: dll starting at 0x75c30000 not found.
Error: dll starting at 0x76c60000 not found.
Error: dll starting at 0x76b60000 not found.
[New thread 3764.0x4c4]
Usage: /a <input_file>

Program exited with code 01.[/m]

What does this mean?? (Wondering)

Did you compile with [m]-g[/m]? (Wondering)
 
  • #55
I like Serena said:
Did you compile with [m]-g[/m]? (Wondering)

Yes, I compiled it as followed:

[m]gcc -g main.c stars.c[/m]
 
  • #56
mathmari said:
Yes, I compiled it as followed:

[m]gcc -g main.c stars.c[/m]

What do you get if you type [m]gcc -v[/m]? (Wondering)
And what for [m] gdb -v[/m]?
 
  • #57
I like Serena said:
What do you get if you type [m]gcc -v[/m]? (Wondering)

Do you mean that I have to type [m]gcc -v[/m] without [m]main.c stars.c[/m] ?? (Wondering)
 
  • #58
mathmari said:
Do you mean that I have to type [m]gcc -v[/m] without [m]main.c stars.c[/m] ?? (Wondering)

Yes.

It will give the version and configuration of the gcc respectively the gdb version you are using.
It appears they are somehow not compatible. :confused:

Btw, didn't you have gdb running properly before? (Wondering)
 
  • #59
When I type [m]gcc -v[/m] I get the following:

[m]Reading specs from /usr/lib/gcc/i686-pc-cygwin/3.4.4/specs
Configured with: /managed/gcc-build/final-v3-bootstrap/gcc-3.4.4-999/configure --verbose --program-suffix=-3 --prefix=/usr --exec-prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --enable-languages=c,ada,c++,d,f77,pascal,java,objc --enable-nls --without-included-gettext --enable-version-specific-runtime-libs --without-x --enable-libgcj --disable-java-awt --with-system-zlib --enable-interpreter --disable-libgcj-debug --enable-threads=posix --enable-java-gc=boehm --disable-win32-registry --enable-sjlj-exceptions --enable-hash-synchronization --enable-libstdcxx-debug
Thread model: posix
gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)[/m]
When I type [m]gdb -v[/m] I get the following:

[m]GNU gdb 6.8.0.20080328-cvs <cygwin-special>
Copyright <C> 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <301 Moved Permanently>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details.
This GDB was configured as "i686-pc-cygwin".[/m]
 
  • #60
When I check the same thing, I get:
[m]\$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/lto-wrapper.exe
...
gcc version 4.8.3 (GCC)[/m]

[m]\$ gdb -v
GNU gdb (GDB) 7.8
...
This GDB was configured as "x86_64-pc-cygwin".
[/m]

What is drawing my attention is that you appear to have a "cygming special".
Do you perhaps have the so called MinGW version of the gcc compiler? (Wondering)
If so, perhaps that may be incompatible with the version of gdb that you have.
(Not to mention that your version is apparently pretty old.)

Ideally, you'd use the setup of Cygwin to install both gcc and gdb.
If you do it like that, both should work in conjunction with each other. (Thinking)

Otherwise, we'll have to use a more primitive way to figure out where your segmentation fault is coming from. (Sweating)
 
  • #61
GCC 3.4.4 was released in mid 2005, almost a decade ago. GDB 6.8 is from early 2008, and you have the cvs (snapshot?) version. They were most definitely not meant for each other. Please, mathmari, do yourself a favour and upgrade your toolchain. Trying to use broken tools is just not worth it.​
 
  • #62
I downloaded Cygwin again I chose the following packages that should be satisfied:

[m]ca-certificates (2.1-1)
CA root certificates
Required by: libopenssl100

cygwin-debuginfo (1.7.33-1)
Debug info for cygwin
Required by: cygwin64-gcc-debuginfo, gcc-debuginfo, gdb-debuginfo, cygwin-debuginfo

cygwin-devel (1.7.33-1)
Core development files
Required by: gcc-core

libargp (20110921-2)
Interface for parsing command line arguments
Required by: getent

libatomic1 (4.8.3-4)
GCC C11/C++11 locked atomics runtime library
Required by: gcc-core

libcharset1 (1.14-2)
GNU character set conversion library and utilities - runtime (2)
Required by: libiconv

libcloog-isl4 (0.18.0-2)
CLooG Chunky Loop Generator (runtime)
Required by: gcc-core, gcc-g++

libdb4.8 (4.8.30-1)
Oracle Berkeley DB (db4.8 - C and C++ libs)
Required by: perl, python

libffi6 (3.0.13-1)
Portable foreign function interface library
Required by: python, libp11-kit0

libgmp10 (6.0.0a-1)
Library for arbitrary precision arithmetic (C runtime)
Required by: coreutils, gawk, gcc-core, gcc-g++, libmpfr4, libcloog-isl4, libisl10, libmpc3, mingw-gcc-g++, mingw-gcc-core

libgomp1 (4.8.3-4)
GCC OpenMP runtime library
Required by: gcc-core

libiconv (1.14-2)
GNU character set conversion library and utilities
Required by: man-db, libintl-devel

libintl-devel (0.18.3.2-2)
GNU Internationalization runtime library
Required by: libuuid-devel

libisl10 (0.11.1-2)
Integer Set Library (runtime)
Required by: gcc-core, gcc-g++

libmpc3 (1.0.2-1)
C library for multiple-precision floating-point computations with exact rounding (runtime)
Required by: gcc-core, gcc-g++, mingw-gcc-g++, mingw-gcc-core

libmpfr4 (3.1.2-1)
A library for multiple-precision floating-point arithmetic with exact rounding (runtime)
Required by: gawk, gcc-core, gcc-g++, libmpc3, mingw-gcc-g++, mingw-gcc-core

libopenssl100 (1.0.1j-1)
A general purpose cryptography toolkit with TLS implementation (runtime)
Required by: python, lynx, perl_vendor

libp11-kit0 (0.20.7-1)
PKCS#11 module library
Required by: p11-kit

libpcre1 (8.35-1)
Perl Compatible Regular Expressions UTF-8 runtime
Required by: grep

libpipeline1 (1.3.0-3)
C library for manipulating pipelines of subprocesses - runtime.
Required by: man-db

libquadmath0 (4.8.3-4)
GCC Quad-Precision Math runtime library
Required by: gcc-core

libsmartcols1 (2.25.2-1)
Tabular data formatting library (runtime)
Required by: util-linux

libsqlite3_0 (3.8.7.2-1)
An embeddable SQL database engine (library)
Required by: python

libtasn1_6 (4.2-1)
Tiny ASN.1 library (runtime)
Required by: p11-kit, p11-kit-trust

libuuid-devel (2.25.2-1)
Universally Unique ID library (development)
Required by: python

libxml2 (2.9.2-1)
GNOME XML library (runtime)
Required by: perl_vendor

lynx (2.8.7-1)
Text-based Web browser
Required by: man-db

mingw-binutils (2.23.1-1)
Binutils for MinGW.org Win32 toolchain
Required by: mingw-gcc-core

mingw-gcc-core (4.7.3-1)
GNU Compiler Collection (C, OpenMP)
Required by: mingw-gcc-g++, mingw-gcc-g++

mingw-gcc-g++ (4.7.3-1)
GNU Compiler Collection (C++)
Required by: gcc-mingw-g++

mingw-pthreads (20110507-2)
Libpthread for MinGW.org Win32 toolchain
Required by: mingw-gcc-core

p11-kit (0.20.7-1)
PKCS#11 module tool
Required by: ca-certificates

p11-kit-trust (0.20.7-1)
PKCS#11 module library
Required by: ca-certificates

perl_vendor (5.14.2-3)
Additional vendor modules previously packaged in perl-5.10
Required by: texinfo

popt (1.16-1)
Library for parsing cmdline parameters
Required by: libpopt0

python (2.7.8-1)
Python language interpreter
Required by: gdb

tcl (8.5.11-1)
Tool Command Language
Required by: tcltk

vim-common (7.4.527-1)
Vi IMproved - enhanced vi editor (common runtime)
Required by: vim

w32api-headers (3.3.0-2)
MinGW-w64 Windows API headers for Cygwin
Required by: gcc-core, w32api

w32api-runtime (3.3.0-1)
MinGW-w64 Windows API import libraries for Cygwin
Required by: gcc-core, w32api

windows-default-manifest (6.4-1)
Default Windows application manifest
Required by: gcc-core

xxd (7.4.527-1)
Hexdump utility
Required by: vim-common

zlib-devel (1.2.8-3)
Gzip de/compression library (development)
Required by: binutils

_autorebase (000713-1)
Run rebaseall automatically
Required by: cygwin, file, gawk, gcc-core, libblkid1, libgcc1, libssp0, libstdc++6, libuuid1, man-db, mingw-runtime, perl, zlib0, libgmp10, libatomic1, libgomp1, libmpc3, libquadmath0, python, libpcre1, libpipeline1, perl_vendor, libsmartcols1, libopenssl100, libsqlite3_0, libxml2, p11-kit-trust, libp11-kit0, libtasn1_6
[/m]

Are these the correct one?? (Wondering)
 
  • #63
mathmari said:
Are these the correct one?? (Wondering)

I hope so! (Doh)

Does it work now? (Wondering)
 
  • #64
Yes, it works now! (Smile)

For [m]gcc -v[/m] I get:

[m]Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-pc-cygwin/4.8.3/lto-wrapper.exe
Target: i686-pc-cygwin
...
gcc version 4.8.3 (GCC)[/m]

and for [m]gdb -v[/m] I get:

[m]GNU gdb (GDB) 7.8
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-cygwin".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".[/m]
 
Last edited by a moderator:
  • #65
When I write now [m]gcc -g main.c stars.c[/m] and then [m]gdb a.exe[/m] and [m](gdb) r[/m] I get the following:

[m]Starting program: /cygdrive/c/cygwin/a.exe
[New Thread 2460.0xa08]
[New Thread 2460.0x1098]
Usage: /a <input_file>
[Thread 2460.0x1098 exited with code 1]
[Inferior 1 (process 2460) exited with code 01][/m]

What does this mean?? (Wondering)
 
  • #66
Seems like your program a.exe wants an input file, and is printing out its usage information... what does your main function look like, and have you tried following the instructions it's giving you and trying:
Code:
gdb a.exe <input_file>
where <input_file> is to be replaced with a suitable input file, I have no idea what that would be, I haven't followed the thread which is a bit of a mess anyway, it would help a lot if you posted your entire program.
 
  • #67
Bacterius said:
Seems like your program a.exe wants an input file, and is printing out its usage information... what does your main function look like, and have you tried following the instructions it's giving you and trying:
Code:
gdb a.exe <input_file>
where <input_file> is to be replaced with a suitable input file

Indeed!

However, the command should be:
Code:
gdb --args a.exe input.txt
Otherwise the input file is interpreted as a core dump. (Wasntme)
 
  • #68
Ok! Now I get the following:

[m]Starting program: /cygdrive/c/cygwin/a.exe file.txt
[New Thread 2072.0x1674]
[New Thread 2072.0x93c]

...

Program received signal SIGSEGV, Segmentation fault.
0x004024e6 in destruction (solid=7620203, gap=5000) at stars.c:309
309 sum=sum+f->gap;
[/m]

Why do I get a segmentation fault at this point?? (Wondering) The function destruction() is the following:

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

	for(i=0; i<max; i++){
		if(StarS[j].ffplan[i].fp == INT_MAX){
			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;
	
}
 
Last edited by a moderator:
  • #69
mathmari said:
[m]Program received signal SIGSEGV, Segmentation fault.
0x004024e6 in destruction (solid=7620203, gap=5000) at stars.c:309
309 sum=sum+f->gap;
[/m]

Why do I get a segmentation fault at this point?? (Wondering)

Because you are trying to dereference [m]f[/m] when it is not a valid pointer. (Doh)

Shouldn't there be a check whether [m]f[/m] is NULL or not? (Wondering)
 
  • #70
I like Serena said:
Because you are trying to dereference [m]f[/m] when it is not a valid pointer. (Doh)

Shouldn't there be a check whether [m]f[/m] is NULL or not? (Wondering)

I added the check

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

Now I get the following:

[m]Starting program: /cygdrive/c/cygwin/a.exe file.txt
[New Thread 5184.0x13f4]
[New Thread 5184.0x798]

...

The planetary system doesn't contain any asteroids
D 7620203 5000 failed
[Thread 5184.0x798 exited with code 0]
[Inferior 1 (process 5184) exited normally][/m]

But why doesn't it contain any asteroids?? (Wondering)

Didn't we add the asteroids with the following function??

Code:
asteroid_t *asteroid_constitution(int as, int gap, int solid){
	int i, g=0;
	asteroid_t *ast = calloc(1, sizeof(asteroid_t));
	ast->as=as;
	ast->gap=gap;
	ast->prev=NULL;
	ast->next=NULL;
	plansys_t *p=NULL;
	for(i=0; i<Sfreep; i++){
		p=StarS[i].plasy;
		while (p != NULL && p->solid != solid){
			p=p->next;
		}
	}
	if (p->asteroids==NULL){
		p->asteroids=ast;
	}
	else{
                asteroid_t *last=p->asteroids;
                asteroid_t *q=NULL;
                asteroid_t *previous=NULL;
                if(ast->gap < last->gap){
                        ast->prev=NULL;
                        ast->next=last;
                        last->prev=ast;
                        last->gap=last->gap-ast->gap;
                        p->asteroids=ast;
                }
                else{
	                while(g < ast->gap && last->next != NULL){
	                	g=g+last->gap;
                                previous=last;
                                last=last->next;
                }
                if(last != NULL && last->next==NULL){
                        ast->prev=last;
                        ast->next=NULL;
                        last->next=ast;
                        ast->gap=ast->gap-g;
                }
                else{
                        ast->next=last->next;
                        last->next->prev=ast;
                        ast->prev=last;
                        last->next=ast;
                        ast->gap=ast->gap-g;
                        q=ast->next;
                        q->gap=q->gap-ast->gap;
            }
        }
    } 
    return 1;
}

(Wondering)
 
  • #71
mathmari said:
[m]The planetary system doesn't contain any asteroids
D 7620203 5000 failed
[Thread 5184.0x798 exited with code 0]
[Inferior 1 (process 5184) exited normally][/m]

But why doesn't it contain any asteroids?? (Wondering)

Didn't we add the asteroids with the following function??

Which information do you have in your [m]file.txt[/m] regarding solid=7620203 and gap=5000? (Wondering)

Suppose you add:
Code:
	for(i=0; i<Sfreep; i++){
		p=StarS[i].plasy;
		while (p != NULL && p->solid != solid){
			p=p->next;
		}
	}
        printf("asteroid_constitution(as=%d, gap=%d, solid=%d) p=%p\n",
                as, gap, solid, p);[/color]
	if (p->asteroids==NULL){

What is the output that you get regarding solid=7620203? (Wondering)
 
  • #72
I like Serena said:
Which information do you have in your [m]file.txt[/m] regarding solid=7620203 and gap=5000? (Wondering)

The file.txt is the following:

[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]

When I write [m](gdb) r[/m] I get the following:

[m]Starting program: /cygdrive/c/cygwin/a.exe file.txt
[New Thread 6136.0xcc0]
[New Thread 6136.0x1408]

I OK
C 762
StarSystems = 762
OK
B 7620213 762
PlanetarySystems = 7620213
OK
B 7620203 762
PlanetarySystems = 7620213 7620203
OK
A 987 4232 7620203
987 : 4232 : 0 : 0

OK
A 985 1232 7620203
985 : 1232 : 0 : 0

OK
A 986 6344 7620203
986 : 6344 : 0 : 0

OK
The planetary system doesn't contain any asteroids
D 7620203 5000 failed
[Thread 6136.0x1408 exited with code 0]
[Inferior 1 (process 6136) exited normally][/m]
I like Serena said:
Suppose you add:
Code:
	for(i=0; i<Sfreep; i++){
		p=StarS[i].plasy;
		while (p != NULL && p->solid != solid){
			p=p->next;
		}
	}
        printf("asteroid_constitution(as=%d, gap=%d, solid=%d) p=%p\n",
                as, gap, solid, p);[/color]
	if (p->asteroids==NULL){

What is the output that you get regarding solid=7620203? (Wondering)

When I add the command [m]printf("asteroid_constitution(as=%d, gap=%d, solid=%d) p=%p\n",
as, gap, solid, p);[/m]
I get the following:

[m]Starting program: /cygdrive/c/cygwin/a.exe file.txt
[New Thread 6052.0x14f4]
[New Thread 6052.0xe80]

I OK
C 762
StarSystems = 762
OK
B 7620213 762
PlanetarySystems = 7620213
OK
B 7620203 762
PlanetarySystems = 7620213 7620203
OK
asteroid_constitution(as=987, gap=4232, solid=7620203) p=0x80059918
A 987 4232 7620203
987 : 4232 : 0 : 0

OK
asteroid_constitution(as=985, gap=1232, solid=7620203) p=0x80059918
A 985 1232 7620203
985 : 1232 : 0 : 0

OK
asteroid_constitution(as=986, gap=6344, solid=7620203) p=0x80059918
A 986 6344 7620203
986 : 6344 : 0 : 0

OK
The planetary system doesn't contain any asteroids
D 7620203 5000 failed
[Thread 6052.0xe80 exited with code 0]
[Inferior 1 (process 6052) exited normally][/m]

(Wondering)
 
Last edited by a moderator:
  • #73
mathmari said:
When I add the command [m]printf("asteroid_constitution(as=%d, gap=%d, solid=%d) p=%p\n",
as, gap, solid, p);[/m]
I get the following:
(Wondering)

I believe this is the location where your problem is.
The code to find the right [m]p[/m] is wrong.
It will always choose the last star system, instead of the one with the matching [m]as[/m]. (Worried)
 
  • #74
I like Serena said:
I believe this is the location where your problem is.
The code to find the right [m]p[/m] is wrong.
It will always choose the last star system, instead of the one with the matching [m]as[/m]. (Worried)

I changed something...

Code:
for(i=0; i<Sfreep; i++){
		p=StarS[i].plasy;
		while (p->next != NULL && p->solid != solid){
			p=p->next;
			k=i;
		}
	}
	
p=StarS[k].plasy;
	
printf("asteroid_constitution(as=%d, gap=%d, solid=%d) p=%p\n",
                as, gap, solid, p);

Now I get the following:

[m]Starting program: /cygdrive/c/cygwin/a.exe file.txt
[New Thread 4860.0x1668]
[New Thread 4860.0x13d0]

I OK
C 762
StarSystems = 762
OK
B 7620213 762
PlanetarySystems = 7620213
OK
B 7620203 762
PlanetarySystems = 7620213 7620203
OK
asteroid_constitution(as=987, gap=4232, solid=7620203) p=0x80059908
A 987 4232 7620203
987 : 4232 : 0 : 0

OK
asteroid_constitution(as=985, gap=1232, solid=7620203) p=0x80059908
A 985 1232 7620203
985 : 1232 : 0 : 0

OK
asteroid_constitution(as=986, gap=6344, solid=7620203) p=0x80059908
A 986 6344 7620203
986 : 6344 : 0 : 0

OK
The planetary system doesn't contain any asteroids
D 7620203 5000 failed
[Thread 4860.0x13d0 exited with code 0]
[Inferior 1 (process 4860) exited normally][/m]
 
  • #75
mathmari said:
I changed something...

Code:
for(i=0; i<Sfreep; i++){
		p=StarS[i].plasy;
		while (p->next != NULL && p->solid != solid){
			p=p->next;
			k=i;
		}
	}
	
p=StarS[k].plasy;
	
printf("asteroid_constitution(as=%d, gap=%d, solid=%d) p=%p\n",
                as, gap, solid, p);

This will get you the last star system with at least 1 planetary system.
It will not get you the one with the matching [m]solid[/m] identification. (Doh)
 
  • #76
I like Serena said:
This will get you the last star system with at least 1 planetary system.
It will not get you the one with the matching [m]solid[/m] identification. (Doh)

I added a check...

Code:
        int k=-1;
        ...
	for(i=0; i<Sfreep; i++){
		p=StarS[i].plasy;
		while (p->next != NULL && p->solid != solid){
			p=p->next;
			k=i;
		}
		if(p->solid == solid){
			k=i;
		}
	}
	if(k == -1){
		return -1;
	}
	
	p=StarS[k].plasy;
	
        printf("asteroid_constitution(as=%d, gap=%d, solid=%d) p=%p\n",
                as, gap, solid, p);

Do do we get now the right one?? (Wondering)
 
  • #77
mathmari said:
I added a check...
Do do we get now the right one?? (Wondering)

Let's see... (Thinking)

Code:
		p=StarS[i].plasy;
		while (p->next != NULL && p->solid != solid){

What if [m]StarS.plasy[/m] is NULL?
Then we can't use [m]p->next[/m]. (Worried)

Code:
			p=p->next;
			k=i;

Aren't you always setting [m]k[/m] here? Even if we did not find [m]solid[/m]? (Wondering)
 
  • #78
I like Serena said:
What if [m]StarS.plasy[/m] is NULL?
Then we can't use [m]p->next[/m]. (Worried)

Code:
			p=p->next;
			k=i;

Aren't you always setting [m]k[/m] here? Even if we did not find [m]solid[/m]? (Wondering)


Code:
     int k=-1;
        ...
	for(i=0; i<Sfreep; i++){
		p=StarS[i].plasy;
		while (p != NULL && p->next != NULL && p->solid != solid){
			p=p->next;
		}
		if(p->solid == solid){
			k=i;
		}
	}
	if(k == -1){
		return -1;
	}
	
	p=StarS[k].plasy;
	
        printf("asteroid_constitution(as=%d, gap=%d, solid=%d) p=%p\n",
                as, gap, solid, p);

Is it better now?? (Wondering)
 
  • #79
mathmari said:
Code:
     int k=-1;
        ...
	for(i=0; i<Sfreep; i++){
		p=StarS[i].plasy;
		while (p != NULL && p->next != NULL && p->solid != solid){
			p=p->next;
		}
		if(p->solid == solid){
			k=i;
		}
	}
	if(k == -1){
		return -1;
	}
	
	p=StarS[k].plasy;
	
        printf("asteroid_constitution(as=%d, gap=%d, solid=%d) p=%p\n",
                as, gap, solid, p);

Is it better now?? (Wondering)

Better yes... but what will happen if some [m]StarS.plasy[/m] is NULL?
I think you'll still have a segmentation fault. (Worried)

Btw, the check [m]p->next != NULL[/m] is redundant, although it does make the logic more complicated. (Nerd)
 
  • #80
I like Serena said:
Better yes... but what will happen if some [m]StarS.plasy[/m] is NULL?
I think you'll still have a segmentation fault. (Worried)


If we add [m]p != NULL[/m] in the if statement, would still get a segmentation fault if some [m]StarS.plasy[/m] is NULL?? (Wondering)

Code:
int k=-1;
        ...
	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){
			k=i;
		}
	}
	if(k == -1){
		return -1;
	}
	
	p=StarS[k].plasy;
	
        printf("asteroid_constitution(as=%d, gap=%d, solid=%d) p=%p\n",
                as, gap, solid, p);
I like Serena said:
Btw, the check [m]p->next != NULL[/m] is redundant, although it does make the logic more complicated. (Nerd)

But when we leave the while loop don't we have set a [m]p[/m] [m]p->next[/m] which might be [m]NULL[/m] ?? (Wondering)
 
  • #81
mathmari said:
If we add [m]p != NULL[/m] in the if statement, would still get a segmentation fault if some [m]StarS.plasy[/m] is NULL?? (Wondering)


No, because C short circuits logical expressions.
If [m]p == NULL[/m] the if-condition is considered false without ever evaluating [m]p->solid == solid[/m]. (Nerd)


Code:
int k=-1;
        ...
	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){
			k=i;
		}
	}
	if(k == -1){
		return -1;
	}
	
	p=StarS[k].plasy;
	
        printf("asteroid_constitution(as=%d, gap=%d, solid=%d) p=%p\n",
                as, gap, solid, p);

Much better! (Smile)
But when we leave the while loop don't we have set a [m]p[/m] [m]p->next[/m] which might be [m]NULL[/m] ?? (Wondering)

How so? (Wondering)

Within the while-loop, it is always safe to execute [m]p=p->next[/m], and after the while-loop [m]p[/m] points to the planetary system we're interested in.
What else would we want to do with [m]p->next[/m]? (Thinking)
 
  • #82
I like Serena said:
No, because C short circuits logical expressions.
If [m]p == NULL[/m] the if-condition is considered false without ever evaluating [m]p->solid == solid[/m]. (Nerd)

Ahaa... Ok! (Malthe)
I like Serena said:
Much better! (Smile)

(Smile)
I like Serena said:
How so? (Wondering)

Within the while-loop, it is always safe to execute [m]p=p->next[/m], and after the while-loop [m]p[/m] points to the planetary system we're interested in.

I see... (Nerd)

When I add the following at the function

Code:
printf("solid=%p      p->solid==%p \n", solid, p->solid);
	printf("asteroid_constitution(as=%d, gap=%d, solid=%d) p=%p\n",
                as, gap, solid, p);
I get the following: [m]Starting program: /cygdrive/c/cygwin/a.exe file.txt
[New Thread 5100.0x1178]
[New Thread 5100.0x95c]

I OK
C 762
StarSystems = 762
OK
B 7620213 762
PlanetarySystems = 7620213
OK
B 7620203 762
PlanetarySystems = 7620213 7620203
OK
solid=0x74466b p->olsid==0x744675
asteroid_constitution(as=987, gap=4232, solid=7620203) p=0x80059908
A 987 4232 7620203
987 : 4232 : 0 : 0

OK
solid=0x74466b p->solid==0x744675
asteroid_constitution(as=985, gap=1232, solid=7620203) p=0x80059908
A 985 1232 7620203
985 : 1232 : 0 : 0

OK
solid=0x74466b p->solid==0x744675
asteroid_constitution(as=986, gap=6344, solid=7620203) p=0x80059908
A 986 6344 7620203
986 : 6344 : 0 : 0

OK
The planetary system doesn't contain any asteroids
D 7620203 5000 failed
[Thread 5100.0x95c exited with code 0]
[Inferior 1 (process 5100) exited normally][/m]

Does this mean that [m]p[/m] still doesn't point to the correct planetary system?? (Wondering)
 
  • #83
mathmari said:
Does this mean that [m]p[/m] still doesn't point to the correct planetary system?? (Wondering)

What do you get if you use:
Code:
int k=-1;
        ...
	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){
			k=i;
                        printf("Found in StarS[%d] solid=%d p->solid==%d StarS[k].plasy=%p\n", 
                               k, solid, p->solid, StarS[k].plasy);[/color]
		}
	}
	if(k == -1){
		return -1;
	}
	
	p=StarS[k].plasy;
	
        printf("asteroid_constitution(as=%d, gap=%d, solid=%d) k=%d p=%p\n",
               as, gap, solid, p);[/color]
(Wondering)
 
  • #84
I like Serena said:
What do you get if you use:
Code:
int k=-1;
        ...
	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){
			k=i;
                        printf("Found in StarS[%d] solid=%d p->solid==%d StarS[k].plasy=%p\n", 
                               k, solid, p->solid, StarS[k].plasy);[/color]
		}
	}
	if(k == -1){
		return -1;
	}
	
	p=StarS[k].plasy;
	
        printf("asteroid_constitution(as=%d, gap=%d, solid=%d) k=%d p=%p\n",
               as, gap, solid, p);[/color]
(Wondering)

I get the following:

[m]Starting program: /cygdrive/c/cygwin/a.exe file.txt
[New Thread 5248.0x1484]
[New Thread 5248.0x14a8]

I OK
C 762
StarSystems = 762
OK
B 7620213 762
PlanetarySystems = 7620213
OK
B 7620203 762
PlanetarySystems = 7620213 7620203
OK
Found in StarS[0] solid=7620203 p->solid==7620203 StarS[k].plasy=0x80059908
asteroid_constitution(as=987, gap=4232, solid=7620203) p=0x80059908
A 987 4232 7620203
987 : 4232 : 0 : 0

OK
Found in StarS[0] solid=7620203 p->solid==7620203 StarS[k].plasy=0x80059908
asteroid_constitution(as=985, gap=1232, solid=7620203) p=0x80059908
A 985 1232 7620203
985 : 1232 : 0 : 0

OK
Found in StarS[0] solid=7620203 p->solid==7620203 StarS[k].plasy=0x80059908
asteroid_constitution(as=986, gap=6344, solid=7620203) p=0x80059908
A 986 6344 7620203
986 : 6344 : 0 : 0

OK
The planetary system doesn't contain any asteroids
D 7620203 5000 failed
[Thread 5248.0x14a8 exited with code 0]
[Inferior 1 (process 5248) exited normally][/m]
 
  • #85
Good! (Happy)

I believe we have confirmed that we're looking at the right star system in the code snippet you provided. (Nod)
That is, the one that matches [m]as[/m], and that contains a planetary system with identification [m]solid[/m].

What's next? (Wondering)
 
  • #86
I like Serena said:
Good! (Happy)

I believe we have confirmed that we're looking at the right star system in the code snippet you provided. (Nod)
That is, the one that matches [m]as[/m], and that contains a planetary system with identification [m]solid[/m].

Great! (Mmm)
I like Serena said:
What's next? (Wondering)

So, now the function asteroid_constitution() is correct and we have to find the error at the function destruction(), right?? (Wondering)
 
  • #87
mathmari said:
So, now the function asteroid_constitution() is correct and we have to find the error at the function destruction(), right?? (Wondering)

It appears that way yes. (Thinking)
 
  • #88
I like Serena said:
It appears that way yes. (Thinking)

I found out that at the function asteroid_constitution() [m]p->asteroids[/m] is [m]NULL[/m].

I wrote the following, at the end of the function:

Code:
        printf("p->asteroids= %p  \n ", p->asteroids);
        printf("A %d %d %d\n", as, gap, solid);
	while(p->planets != NULL){
			 ...
			  p->asteroids=p->asteroids->next;
	 }
	 printf("p->asteroids= %p  \n ", p->asteroids);

I get the following:

[m]Starting program: /cygdrive/c/cygwin/a.exe file.txt
[New Thread 5260.0x1450]
[New Thread 5260.0x1540]

I OK
C 762
StarSystems = 762
OK
B 7620213 762
PlanetarySystems = 7620213
OK
B 7620203 762
PlanetarySystems = 7620213 7620203
OK
p->asteroids= 0x80059928
A 987 4232 7620203
987 : 4232 : 0 : 0
p->asteroids= 0x0

OK
p->asteroids= 0x80059940
A 985 1232 7620203
985 : 1232 : 0 : 0
p->asteroids= 0x0

OK
p->asteroids= 0x80059958
A 986 6344 7620203
986 : 6344 : 0 : 0
p->asteroids= 0x0

OK
The planetary system doesn't contain any asteroids
D 7620203 5000 failed
[Thread 5260.0x1540 exited with code 0]
[Inferior 1 (process 5260) exited normally][/m]

That means that before the while-loop [m]p->asteroids[/m] is not [m]NULL[/m], but after the while-loop it is [m]NULL[/m]. Why does this occur?? (Wondering)
 
  • #89
mathmari said:
I found out that at the function asteroid_constitution() [m]p->asteroids[/m] is [m]NULL[/m].

I wrote the following, at the end of the function:

Code:
        printf("p->asteroids= %p  \n ", p->asteroids);
        printf("A %d %d %d\n", as, gap, solid);
	while(p->planets != NULL){
			 ...
			  p->asteroids=p->asteroids->next;
	 }
	 printf("p->asteroids= %p  \n ", p->asteroids);

Aha! You found something! (Happy)

That means that before the while-loop [m]p->asteroids[/m] is not [m]NULL[/m], but after the while-loop it is [m]NULL[/m]. Why does this occur?? (Wondering)

Because your changing p->asteroids with [m]p->asteroids=p->asteroids->next;[/m].

I guess you wanted to iterate over the linked list, but you're using the head of the list to do so. Afterwards, that head is not valid any more. Effectively, the linked list is now empty. (Worried)
 
  • #90
I like Serena said:
Aha! You found something! (Happy)

(Malthe)
I like Serena said:
Because your changing p->asteroids with [m]p->asteroids=p->asteroids->next;[/m].

I guess you wanted to iterate over the linked list, but you're using the head of the list to do so. Afterwards, that head is not valid any more. Effectively, the linked list is now empty. (Worried)

Yes, I want to iterate over the linked list and print some information.
How can I do it then, without using the head?? (Wondering)
 
  • #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)
 
  • #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)
 

Similar threads

Replies
1
Views
1K
Replies
20
Views
4K
Replies
5
Views
4K
Back
Top