LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
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 05-13-2004, 04:56 AM   #1
acer_peri
Member
 
Registered: Nov 2003
Location: Beijing, China
Distribution: Tettnang
Posts: 38

Rep: Reputation: 15
"segmentation fault" when run a simple c program


considering the following three file, I use
gcc -c main.c
g++ -c reciprocal.cpp
to compile them, and
g++ -o main.out main.c reciprocal.cpp
to link them, and when I run 'main' with
./main.out
the shell display the following error code:
segmentation fault.

Code:
/*main.c*/
#include <stdio.h>
#include <stdlib.h>
#include "reciprocal.hpp"

int main (int argc, char **argv)
{
  int i;

  i = atoi (argv[1]);
  printf ("The reciprocal of %d is %g\n", i, reciprocal (i));
  return 0;
}


/*reciprocal.cpp*/
#include <cassert>
#include "reciprocal.hpp"

double reciprocal (int i) {
  // I should be non-zero.
  assert (i != 0);
  return 1.0/i;
}


/*reciprocal.hpp*/
#ifdef __cplusplus
extern "C" {
#endif

extern  double reciprocal (int i);

#ifdef __cplusplus
}
#endif

the code is from the book "Advanced Linux programming"
 
Old 05-13-2004, 05:00 AM   #2
acer_peri
Member
 
Registered: Nov 2003
Location: Beijing, China
Distribution: Tettnang
Posts: 38

Original Poster
Rep: Reputation: 15
on running the following file, it also display the segmentation fault error message. But when I run it on Windows xp, it has no error.It is a simple scanner program made by me.
Code:
/*Exp-1 Scanner of C*/
#include<stdio.h>
#include<ctype.h>
#include<string.h>
/*#include<conio.h>*/
#include<stdlib.h>

#define N 20

void scan(FILE *);
int isKeyword(char *);
int isDirective=0;
main(){
	char *fileName="";
	FILE *fPtr;
	printf("Please enter the file name of the C program for scanning: ");
	scanf("%s",fileName);
	if((fPtr = fopen(fileName, "r")) == NULL){
		printf("File could not be opened\n");
		/*getch();*/
		exit(1);
	}
	scan(fPtr);
	return;
}

void scan(FILE *fPtr){
	char *token="", *symbol="", *attr="", ch, s[2];
	while(!feof(fPtr)){
		*token='\x0';
		ch=fgetc(fPtr);
		if(ch=='\n')
			isDirective=0;
		while(isspace(ch))
			ch=fgetc(fPtr);
		if(isdigit(ch)){
			while(isdigit(ch)){
				s[0]=ch; s[1]='\0';
				strcat(token,s);
				ch=fgetc(fPtr);
			}
			if(isDirective==0){
				symbol="Number";
				attr=token;
			}
			else{
				symbol="Number in directive";
				attr=token;
			}
			fseek(fPtr,-1L, SEEK_CUR); /*input pointer back a character*/
		}
		else if(isalpha(ch)){
			while(isalnum(ch)){
				s[0]=ch; s[1]='\0';
				strcat(token,s);
				ch=fgetc(fPtr);
			}
			fseek(fPtr,-1L,SEEK_CUR);
			if(isKeyword(token))
				symbol="Keyword";
			else if(isDirective==0)
				symbol="Identifier";
			else
				symbol="ID in directive";
			attr=token;
		}
		else switch(ch){
			case '/':
				if(fgetc(fPtr)=='/'){
					ch=fgetc(fPtr);
					while(ch!='\n'){
						s[0]=ch; s[1]='\0';
						strcat(token,s);
						ch=fgetc(fPtr);
					}
					fseek(fPtr,-1L,SEEK_CUR);
					symbol="Single line comment";
					attr=token;
				}
				if(fgetc(fPtr)=='*'){
					ch=fgetc(fPtr);
L1:					while(ch!='*'){
						s[0]=ch; s[1]='\0';
						strcat(token,s);
						ch=fgetc(fPtr);
					}
					if(ch=='/'){
						symbol="Multiple line comment";
						attr=token;
					}
					else
						goto L1;
				}
				break;
			/*case '#':
				isDirective=1;
				while(isalpha(ch)){
					s[0]=ch; s[1]='\0';
					strcat(token,s);
					ch=fgetc(fPtr);
				}
				fseek(fPtr,-1L,SEEK_CUR);
				symbol="directive";
				attr=token;
				break;*/
			case '=':
				if(fgetc(fPtr)=='='){
					symbol="Relational-Operator";
					attr="EQ";
				}
				else{
					fseek(fPtr,-1L,SEEK_CUR);
					symbol="Assign-Operator";
					attr="=";
				}
				break;
			case ';':
				symbol="End-of-statement";
				attr=";";
				break;
			case ':':
				symbol="Label";
				attr=":";
				break;
			case '<':
				if(isDirective==1){
					symbol="Directive-left";
					attr="<";
				}
				else if(fgetc(fPtr)=='='){
					symbol="Relational-Operator";
					attr="LE";
				}
				else{
					fseek(fPtr,-1L,SEEK_CUR);
					symbol="Relational-Operator";
					attr="LT";
				}
				break;
			case '>':
				if(isDirective==1){
					symbol="Directive-right";
					attr=">";
				}
				else if(fgetc(fPtr)=='='){
					symbol="Relational-Operator";
					attr="GE";
				}
				else{
					fseek(fPtr,-1L,SEEK_CUR);
					symbol="Relational-Operator";
					attr="GT";
				}
				break;
			case '!':
				if(fgetc(fPtr)=='='){
					symbol="Relational-Operator";
					attr="NE";
				}
				else{
					fseek(fPtr,-1L,SEEK_CUR);
					symbol="Logical-Operator";
					attr="NOT";
				}
				break;
			case '{':
				symbol="Block-begin";
				attr="{";
				break;
			case '}':
				symbol="Block-end";
				attr="}";
				break;
			default:
				s[0]=ch; s[1]='\0';
				symbol="Other";
				attr=s;
				break;
		}
		printf("Symbol: %s\t\tAttr: %s\n",symbol,attr);
		/*getch();*/
	}
}

int isKeyword(char *token){
	char *key="void int char float double long unsigned if else switch case do while break continue return union typedef const default enum goto short sizeof static struct";
	if(strstr(key,token) != NULL)
		return 1;
	else
		return 0;
 
Old 05-13-2004, 06:04 AM   #3
Ma3oiS
LQ Newbie
 
Registered: May 2004
Posts: 12

Rep: Reputation: 0
Hi,

in the first program the "bad" line is
Code:
   i = atoi(argv[1]);
because when you supply no parameters to your ./main.out it will call atoi(0) and that causes segmentation fault. You should replace it with
Code:
   if (argv[1]) i = atoi(argv[1]);
   else i = 0; // or something else
The second program have more errors. You should read more about how to work with strings (or with char*) in C/C++.

e.g., when you do
Code:
 char *variable;
 variable = "constant string"
you didn't copied string to your variable, but you only made your variable to point to that string and because it's constant string you can't do *variable='x' (as you do in your scan() function).
And secondly you call scanf("%s",fileName); but you need firstly to allocate space for it or declare it as char fileName[400] or similar.

Bye
Ma3oiS
 
Old 05-14-2004, 06:37 AM   #4
cjp
Member
 
Registered: Dec 2003
Location: the Netherlands
Distribution: SuSE 9.0
Posts: 54

Rep: Reputation: 15
This is wrong:

Code:
int main (int argc, char **argv)
{
  int i;

  i = atoi (argv[1]);
  printf ("The reciprocal of %d is %g\n", i, reciprocal (i));
  return 0;
}
because you get element 1 of the argv array, while this array only contains one element (the program's name) when the program is started without arguments. To check if this is the case, try this:

Code:
int main (int argc, char **argv)
{
  int i;

  if(argc < 2)
  {
    printf("You didn't provide an argument\n");
    return 1;
  }

  i = atoi (argv[1]);
  printf ("The reciprocal of %d is %g\n", i, reciprocal (i));
  return 0;
}
 
Old 05-27-2004, 05:00 PM   #5
acer_peri
Member
 
Registered: Nov 2003
Location: Beijing, China
Distribution: Tettnang
Posts: 38

Original Poster
Rep: Reputation: 15
Ma3oiS, cjp, thanks!
Ma3oiS, your advice of the 2nd program is very useful,
I add three allocation statements and the program run free of error!
Code:
token=malloc(100);
symbol=malloc(100);
attr=malloc(100);
 
Old 05-27-2004, 05:06 PM   #6
acer_peri
Member
 
Registered: Nov 2003
Location: Beijing, China
Distribution: Tettnang
Posts: 38

Original Poster
Rep: Reputation: 15
these days, I've add some content to it.
now the program isit can recognize dec, oct, hex number; keywords, some symbol)
Code:
/*Exp-1 Scanner of C*/
#include<stdio.h>
#include<ctype.h>
#include<string.h>
/*#include<conio.h>*/
#include"userlib.c" /*getch() function*/
#include<stdlib.h>

void scan(FILE *);
int isKeyword(char *);
int isHex(char);
int isOct(char);

main(){
	 char fileName[100]; 
	FILE *fPtr;
	printf("Please enter the file name of the C program for scanning: ");
	scanf("%s",fileName);
	if((fPtr = fopen(fileName, "r")) == NULL){
		printf("File could not be opened\n");
		getch();
		exit(1);
	}
	scan(fPtr);
	return;
}

void scan(FILE *fPtr){
	char *token, *symbol, *attr, ch, s[2];
	token=malloc(100);symbol=malloc(100);attr=malloc(100); 
	while(!feof(fPtr)){
		*token='\0';
		ch=fgetc(fPtr);
		while(isspace(ch))
			ch=fgetc(fPtr);
		if(isdigit(ch)){
			if(ch!='0'){
				while(isdigit(ch)){
					s[0]=ch; s[1]='\0';
					strcat(token,s);
					ch=fgetc(fPtr);
				}
				symbol="INT10";
				attr=token;
			}
			else{
				ch=fgetc(fPtr);
 				if(isOct(ch)){
					while(isOct(ch)){
						s[0]=ch; s[1]='\0';
						strcat(token,s);
						ch=fgetc(fPtr);
					}
					symbol="INT8";
					attr=token;
				}
				else if(ch=='x'||ch=='X'){
					ch=fgetc(fPtr);
					if(isHex(ch)){
						while(isHex(ch)){
							s[0]=ch; s[1]='\0';
							strcat(token,s);
							ch=fgetc(fPtr);
						}
						symbol="INT16";
						attr=token;
					}
				}
				else{
					symbol="INT10";
					attr="0";
				}
			}
			fseek(fPtr,-1L, SEEK_CUR); /*input pointer back a character*/
		}
		else if(isalpha(ch)){
			while(isalnum(ch)){
				s[0]=ch; s[1]='\0';
				strcat(token,s);
				ch=fgetc(fPtr);
			}
			fseek(fPtr,-1L,SEEK_CUR);
			if(isKeyword(token))
				symbol="Keyword";
			else
				symbol="Identifier";
				attr=token;
		}
		else switch(ch){
			case '/':
				symbol="Arithmetic-Operator";
				attr="/";
				break;
			case '*':
				symbol="Arithmetic-Operator";
				attr="*";
				break;
			case '+':
				if(fgetc(fPtr)=='+'){
					symbol="Increment";
					attr="++";
				}
				else{
					fseek(fPtr,-1L,SEEK_CUR);
					symbol="Arithmetic-Operator";
					attr="+";
				}
				break;
			case '-':
				if(fgetc(fPtr)=='-'){
					symbol="Decrement";
					attr="--";
				}
				else{
					fseek(fPtr,-1L,SEEK_CUR);
					symbol="Arithmetic-Operator";
					attr="-";
				}
				break;
			case '=':
				if(fgetc(fPtr)=='='){
					symbol="Relational-Operator";
					attr="EQ";
				}
				else{
					fseek(fPtr,-1L,SEEK_CUR);
					symbol="Assign-Operator";
					attr="=";
				}
				break;
			case ';':
				symbol="End-of-statement";
				attr=";";
				break;
			case ':':
				symbol="Label";
				attr=":";
				break;
			case '<':
				if(fgetc(fPtr)=='='){
					symbol="Relational-Operator";
					attr="LE";
				}
				else{
					fseek(fPtr,-1L,SEEK_CUR);
					symbol="Relational-Operator";
					attr="LT";
				}
				break;
			case '>':
				if(fgetc(fPtr)=='='){
					symbol="Relational-Operator";
					attr="GE";
				}
				else{
					fseek(fPtr,-1L,SEEK_CUR);
					symbol="Relational-Operator";
					attr="GT";
				}
				break;
			case '!':
				if(fgetc(fPtr)=='='){
					symbol="Relational-Operator";
					attr="NE";
				}
				else{
					fseek(fPtr,-1L,SEEK_CUR);
					symbol="Logical-Operator";
					attr="NOT";
				}
				break;
			case '(':
				symbol="Left-Parenth";
				attr="(";
				break;
			case ')':
				symbol="Right-Parenth";
				attr=")";
				break;
			case '{':
				symbol="Block-Begin";
				attr="{";
				break;
			case '}':
				symbol="Block-End";
				attr="}";
				break;
			case '"':
				symbol="String-Quote";
				attr="\"";
				break;
			case '\'':
				symbol="Char-Quote";
				attr="'";
				break;
			case ',':
				symbol="Comma-Operator";
				attr=",";
				break;
			default:
				s[0]=ch; s[1]='\0';
				symbol="Other";
				attr=s;
				break;
		}
		printf("Symbol: %19s\tAttr: %8s\n",symbol,attr);
		getch();
	}
}

int isKeyword(char *token){
	int i;
	char *key[ ]={"auto","break","case","char","const","continue","default","do","double","else",
		"enum","extern","float","for","goto","if","int","long","register","return","short","signed",
		"sizeof","static","struct","switch","typedef","union","unsigned","void","volatile","while"};
	for(i=0;i<=25;i++)
       	if(strcmp(token,key[i])==0)
			return 1;
	return 0;
}

int isHex(char ch){
	if(isdigit(ch)||tolower(ch)=='a'||tolower(ch)=='b'||tolower(ch)=='c'
		||tolower(ch)=='d'||tolower(ch)=='e'||tolower(ch)=='f')
		return 1;
	return 0;
}

int isOct(char ch){
	if(isdigit(ch)&&ch!='8'&&ch!='9')
		return 1;
	return 0;
}

Last edited by acer_peri; 05-27-2004 at 05:11 PM.
 
Old 05-27-2004, 07:18 PM   #7
The_Nerd
Member
 
Registered: Aug 2002
Distribution: Debian
Posts: 540

Rep: Reputation: 32
IsHex:
Code:
int i;
for (i=0;string[i]!=0;i++)
{
    if ((tolower(string[i])<'a'||tolower(string[i])>'f')&&(string[i]<'0'||string[i]>'9')) return false;
}
return true;
IsOct:
Code:
int i;
for (i=0;string[i]!=0;i++) if ((string[i]>'7'||string[i]<'0')) return false;
return true;
 
Old 05-27-2004, 07:22 PM   #8
The_Nerd
Member
 
Registered: Aug 2002
Distribution: Debian
Posts: 540

Rep: Reputation: 32
Oh! Sorry! I didn't understand your last post. I thought you were having problems with IsHex and IsOct... Don't know why I thought that...
 
Old 05-27-2004, 07:50 PM   #9
itsme86
Senior Member
 
Registered: Jan 2004
Location: Oregon, USA
Distribution: Slackware
Posts: 1,246

Rep: Reputation: 59
One thing I see is that you're allocating 100 bytes of memory and saving the pointer to it to the attr variable. But then later you're doing things like attr=token and attr=")". This effectively loses that 100 bytes of memory you allocated and creates a memory leak. It's impossible to free() that memory one you lose the pointer to it.

EDIT - You're doing the same thing with the symbol variable.
 
Old 05-27-2004, 11:36 PM   #10
acer_peri
Member
 
Registered: Nov 2003
Location: Beijing, China
Distribution: Tettnang
Posts: 38

Original Poster
Rep: Reputation: 15
Quote:
Originally posted by itsme86
One thing I see is that you're allocating 100 bytes of memory and saving the pointer to it to the attr variable. But then later you're doing things like attr=token and attr=")". This effectively loses that 100 bytes of memory you allocated and creates a memory leak. It's impossible to free() that memory one you lose the pointer to it.

EDIT - You're doing the same thing with the symbol variable.

How to solve the problem you've pointed?
How to assign pointer attr and symbol to another string value, which don't cause memory or other problem?
 
Old 05-27-2004, 11:38 PM   #11
acer_peri
Member
 
Registered: Nov 2003
Location: Beijing, China
Distribution: Tettnang
Posts: 38

Original Poster
Rep: Reputation: 15
Quote:
Originally posted by The_Nerd
IsHex:
Code:
int i;
for (i=0;string[i]!=0;i++)
{
    if ((tolower(string[i])<'a'||tolower(string[i])>'f')&&(string[i]<'0'||string[i]>'9')) return false;
}
return true;
IsOct:
Code:
int i;
for (i=0;string[i]!=0;i++) if ((string[i]>'7'||string[i]<'0')) return false;
return true;

thanks, yours is good, by mine is also work.
 
Old 05-28-2004, 04:14 AM   #12
Ma3oiS
LQ Newbie
 
Registered: May 2004
Posts: 12

Rep: Reputation: 0
Hi,

you don't need to do symbol=malloc(100); because you assign to this variable only constant string without further
appending or changing characters in it. You can even delete attr=malloc(100); and it will work, but I don't recommend it
for further developing of your program. Maybe this helps you understand how to work with strings:

char *c, *d, *e;
c="Hello"; // OK
// c[0]='S'; // error -> c points to constant string and can't be changed
// free(c); // error -> you can't free constant string
c=(char*)malloc(20); //OK -> you allocated 20bytes; let say it's at memory address A
// c="Hello"; // not OK, because you've lost pointer to memory address A and can't free() (dealocate) this memory
c[0]='C'; c[1]='\0'; //OK;
// c[20]='\0'; // error -> 20 is out of range

d=c; // OK; variables d,c points to the same memory address (A)
d[0]='S'; // OK; now c[0]=='S'

// for copying string to another string use function strcpy(char *dest, const char *src)
// but remember that dest must be allocated to at least 1+strlen(src) bytes

d="Hm";
// strcpy(d, c); // error
d=(char*) malloc(20); // let say we allocated memory at address B
strcpy(d, c); // OK, string "S" copied to address B
d==c; // false; they point to different adresses
strcmp(d, c); // returns 0 -> strings are equal

e=d;
free(e); // OK; deallocated B
free(c); // OK; deallocated A
// free(d); // error; already deallocated

And there are also some different rules in declaration:
char *a="Th"; is equal to char *a; a="Th";
char a[7]="Th"; is equal to char a[7]; a[0]='T'; a[1]='h'; a[2]='\0';


So back to your program - with your variable attr you always do attr=token; or attr="const. string";
You can do this without attr=malloc(100); but remember that in the first case if you later change string pointed to by
variable token that this will also change string pointed to by variable attr (because attr==token).
Therefore you should malloc it and instead of attr=token; use strcpy(attr, token); (and then, of course, also instead
of attr="const. string"; use strcpy(attr, "const. string"); to be able to free(attr) at the end of your scan() function).

And last thing, you don't need isHex(char) because there's isxdigit(char) in ctype.h

Bye
Ma3oiS
 
  


Reply



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
GCC Compiling (Linux), "Segmentation Fault" Kenji Miyamoto Programming 2 01-13-2005 01:44 AM
Segmentation fault with asm("int 0x0f") justthething Programming 1 08-02-2004 01:43 PM
why iam getting problems like "...too many files opened" or "segmentation fault" naren_0101bits Linux - Newbie 2 07-19-2004 12:20 PM
"Segmentation Fault" error message when trying to run Yahoo Messenger on Linux 8.0 niranjanpage Linux - Software 6 10-27-2003 01:21 AM
f-prot anti-virus "Segmentation fault" error and other weird stuff dalek Linux - Software 9 10-22-2003 07:37 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 12:29 AM.

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
Open Source Consulting | Domain Registration