C code : Segmentation fault

Hi Friends,
I have written a small code in C which performs the below operations

Task : 1 ) read line by line from a file.

      2 \) assuming 3th and 4th fields of the file as GN and GNTO

      3 \) The target file should contain all the fields except GNTO.


      4 \) The target file should populate records starting from GN and GNTO

       i.e., if GN is 1 and GNTO is 4 of the same line
      then 
     anything,anything,1,anything,anything
     anything,anything,2,anything,anything
     anything,anything,3,anything,anything
     anything,anything,4,anything,anything

      so i have used a for loop like below.

     for \( gn ; gn<=gn_to;gn\+\+\)
     populate into target file

Problem.: the code is giving me segmentation fault. Unable to find out where it is and why it is. Please help

Below is the source code.

definitions.h
------------

// Macro definitions
#define _EXIT_SUCCESS 0  // return value of exit on Success
#define _EXIT_FAILURE 1  // return value of exit on Failure
#define _ARGS 2          // Number of Arguments passed to the calling script
#define _BUFFER 1024      
#define _CHUNK 100      
#define _STREAM(x,y) fopen(x,y)  // Alias for Read/Write to files

// Directory definitions
extern char *SRC_DIR="/home/hhulaman/1516/source/";  // Source directory path
extern char *LOG_DIR="/home/hhulaman/1516/log/";  // Log directory path
extern char *TMP_DIR="/home/hhulaman/1516/work/";  // Work directory path
extern char *ARCH_DIR="/home/hhulaman/1516/archive/";  // Archive directory path

// File names and extensions
extern char *LOG_NAME="FAP_PORT_OUT.";   // Log file name
extern char *FIELD_SEP="|";   // Source file field separator
extern char *LOG_EXT=".log";  // log file extension
extern char *TMP_EXT=".Tmp";  // Tmp file extension
extern char *TRG_EXT=".Trg";  // Target file extension ( temp file )
extern char *ARCH_EXT=".Arch";  // Archive file extension
extern char DIR_SEP='/';      // Directory separator

port.c
------

#include <stdio.h>   
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include "definitions.h"  /* Include the definitions.h file so as to use environment variables. */


/* prototypes */
int count_digit( int process_id );

int main(int argc, char *argv[])
    {
    FILE *log_stream, *source_stream, *data_stream, *arch_stream, *target_stream, *temp_stream ;
    char *tmp_str, *ref_tmp_str, *mod_str, *ref_mod_str, *field, file_name[_CHUNK], curr_byte, prev_byte;
    unsigned short int pos = 0, digit;
    int record_cnt, decimal, sign;
    double gn, gn_to;
    pid_t pid;
    time_t cTime;    

    /**************************************************************/
    /*STRUCTURE AND VARIABLES FOR FAP PORT FILE ENTRY*/
    /**************************************************************/

    struct fap_port_out
    {
        char file_extraction_date[ 30 ];
        char row_id[ 30 ];
        char gn[ 30 ];
        char gn_to[ 30 ];
        char port_type[ 30 ];
        char completion_date[ 30 ];
        char donor_id[ 30 ];
        char vfone_submission_date[ 30 ];
        char min_due_date[ 30 ];
        char postpay_tariff[ 30 ];
        char con_status[ 30 ];
        char reject_code[ 150 ];
        struct fap_port_out *link;
    } *port_point , *port_start , *port_prior ;

    cTime = time( NULL );
    
    if ( ( pid = getpid() ) < 0 )         //get the process id
    {
        printf( "\t[Error] : Unable to get the process id....Exiting\n" );
        exit( _EXIT_FAILURE );
    }    

    if ( ( tmp_str = ( char * ) malloc( _BUFFER ) ) == NULL )  /* allocating memory for temporary usage  */
    {
        printf("\n\t[Error] : Memory fault for tmp_str....Exiting\n" );
        exit( _EXIT_FAILURE );;
    }
    
    digit = count_digit( pid );
    strcpy( tmp_str, LOG_DIR );
    strcat( tmp_str, LOG_NAME );
    strcat( tmp_str, ecvt( pid, digit, &decimal, &sign ) );
    strcat( tmp_str, LOG_EXT );
    

    if ( ( log_stream = _STREAM( tmp_str, "w" ) ) == NULL )        //file open for write only
    {
        printf( "\t[Error] : Unable to open file %s....Exiting\n", tmp_str );
        exit( _EXIT_FAILURE );
    }

    fprintf( log_stream, "\n\t[Info] : Start\t\t\t%s\n", ctime( &cTime ) );

    if( argc != _ARGS )  /* validating the number of arguments passed to the program  */
    {
        fprintf( log_stream, "\n\t[Error] : Incorrect number of arguments");
        exit( _EXIT_FAILURE );;
    }
    
    if ( ( source_stream = fopen ( *(++argv) , "r" ) ) == NULL )  /* validating the file mode of the informatica file  */
    {
        printf("\n\t[Error] : Unable to read informatica param file %s",argv);
        exit( _EXIT_FAILURE );;
    }
    
    fscanf( source_stream , "%s" , tmp_str );  /* reading the data file from the informatica file  */
        
    strcpy ( file_name , strrchr ( tmp_str , DIR_SEP ) + 1 );
    
    fprintf( log_stream, "\n\t[Info] : Transforming data file %s", tmp_str );
    
    
    fclose ( source_stream ) ;  /* closing the informatica file  */
    
    
    if ( ( data_stream = fopen ( tmp_str , "r" ) ) == NULL )  /* validating the file mode of the data file  */
    {
        fprintf( log_stream, "\n\t[Error] : Unable to read file %s",tmp_str);
        exit( _EXIT_FAILURE );;
    }

    strcpy ( tmp_str , ARCH_DIR );
    strcat ( tmp_str, file_name );
    strcat ( tmp_str , ARCH_EXT );

    fprintf( log_stream , "\n\t[Info] : Archive file %s\n", tmp_str );

    if ( ( arch_stream = fopen ( tmp_str , "w" ) ) == NULL )  /* validating the file mode of the data file  */
    {
        fprintf( log_stream , "\n\t[Error] : Unable to write to archive file %s",tmp_str);
        exit( _EXIT_FAILURE );;
    }
    
    strcpy ( tmp_str , TMP_DIR );
    strcat ( tmp_str, file_name );
    strcat ( tmp_str , TMP_EXT );

        
    if ( ( temp_stream = fopen ( tmp_str , "w" ) ) == NULL )  /* validating the file mode of the data file  */
    {
        fprintf( log_stream , "\n\t[Error] : Unable to write to temp file %s",tmp_str);
        exit( _EXIT_FAILURE );;
    }

    
    if ( ( field = ( char * ) malloc( _CHUNK ) ) == NULL )  /* allocating memory for field usage  */
    {
        fprintf( log_stream , "\n\t[Error] : Unable to allocate memory for field" );
        exit( _EXIT_FAILURE );;
    }


    if ( (mod_str = (char *) malloc ( _BUFFER ) ) == NULL )
    {
        fprintf( log_stream ,"\n\t[Error] : Unable to allocate memory for mod_str" );
        exit( _EXIT_FAILURE );;
    }        
        
    ref_mod_str = mod_str;
    ref_tmp_str = tmp_str; 
    
    record_cnt = 0;
    
    while ( fgets( tmp_str, _BUFFER, data_stream ) != NULL )
    {
        fputs ( tmp_str , arch_stream );
        ++record_cnt;
        while ( *tmp_str != '\0' )
        {
            curr_byte =  *tmp_str;

            if ( curr_byte == '|' && prev_byte == '|' )
            {
   
                *(mod_str++)='F';
                *(mod_str++)='N';
                *(mod_str++)='U';
                *(mod_str++)='L';
                *(mod_str++)='L';
                *(mod_str++)='|'; 
            }
            else
            {
                   
                *mod_str=curr_byte;
                   mod_str++;
                

            }
            tmp_str++;
            prev_byte = curr_byte;
        }
            
      
        *mod_str='\0';
           mod_str=ref_mod_str;

        if ( ( port_point = ( struct fap_port_out* ) malloc ( sizeof ( struct fap_port_out ) ) ) == NULL )
        {
            fprintf( log_stream, "\n\t[Error] : Unable to allocate memory for port_out");
            exit ( _EXIT_FAILURE );
        }
    
        field = strtok ( mod_str , FIELD_SEP );
        
        pos = 1;
        
        while ( field != NULL )
        {
            if ( !( strcmp( field, "FNULL" ) ) )
            {
                    strcpy( field, "" );
            }
            
            switch ( pos )
            {
                case 1 :
                    strcpy ( port_point->file_extraction_date , field );
                    break;
                case 2 :
                    strcpy ( port_point->row_id , field );
                    break;
                case 3 :
                    strcpy ( port_point->gn , field );
                    break;
                case 4 :
                    strcpy ( port_point->gn_to , field );
                    break;
                case 5 :
                    strcpy ( port_point->port_type , field );
                    break;
                case 6 :
                    strcpy ( port_point->completion_date , field );
                    break;
                case 7 :
                    strcpy ( port_point->donor_id , field );
                    break;
                case 8 :
                    strcpy ( port_point->vfone_submission_date , field );
                    break;
                case 9 :
                    strcpy ( port_point->min_due_date , field );
                    break;
                case 10 :
                    strcpy ( port_point->postpay_tariff , field );
                    break;
                case 11 :
                    strcpy ( port_point->con_status , field );
                    break;
                case 12 :
                    strcpy ( port_point->reject_code , field );
                    break;
                default :
                    fprintf( log_stream , "\n\t[Error] : Extra field at record %d\n",record_cnt );
                    break;
            }

            field = strtok ( NULL , FIELD_SEP );
            pos++;
        }
        
        
        if ( record_cnt == 1 )
        {
            port_start = port_point;
        }

        port_prior->link = port_point;
        port_point->link = NULL;
        port_prior = port_point;

        record_cnt++;
        tmp_str = ref_tmp_str;
        
    
        
        if ( !( strcmp( port_point->gn, "" ) && strcmp( port_point->gn_to, "" ) ) )
        {
            fprintf( log_stream , "\n\t[Error] : At Record No. %d of source file, Can't process...Pls check\n", record_cnt );
            continue;
        }

        gn = atof( port_point->gn );
        gn_to = atof( port_point->gn_to );
        
        for ( ; gn <= gn_to ; gn++ ) 
        fprintf( temp_stream , "%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s",
                  port_point->file_extraction_date,
                 port_point->row_id,
                 gcvt( gn, 20, port_point->gn ),
                 port_point->port_type,
                 port_point->completion_date,
                 port_point->donor_id,
                 port_point->vfone_submission_date,
                 port_point->min_due_date,
                 port_point->postpay_tariff,
                 port_point->con_status,
                 port_point->reject_code
            );    
    }
    fclose ( arch_stream );
    fclose ( temp_stream );
    
    strcpy ( tmp_str , TMP_DIR );
    strcat ( tmp_str, file_name );
    strcat ( tmp_str , TMP_EXT );    

    if ( ( ref_tmp_str = ( char * ) malloc( _CHUNK ) ) == NULL )  /* allocating memory for field usage  */
    {
        fprintf( log_stream , "\n\t[Error] : Unable to allocate memory for ref_tmp_str\n" );
        exit( _EXIT_FAILURE );
    }
    
    strcpy ( ref_tmp_str , SRC_DIR );
    strcat ( ref_tmp_str, file_name );

    
    if ( rename( tmp_str, ref_tmp_str ) )        // Rename tmp file as Target file
    {
        fprintf( log_stream, "\n\t[Error] : Unable to rename %s to %s....Exiting\n", tmp_str, ref_tmp_str );
        exit( _EXIT_FAILURE );
    }    
    fprintf( log_stream, "\n\t[Info] : End\t\t\t%s", ctime( &cTime ) );
    
    free ( ref_tmp_str );
    free ( tmp_str );
    free ( mod_str );
    fclose ( data_stream );
    fclose ( log_stream );
    
    return( _EXIT_SUCCESS );
    }     

    
    
/*************************************************************************
**/
//FUNCTION TO FIND THE NUMBER OF DIGITS
/*************************************************************************
**/

int count_digit( int process_id )
{
    int cnt = 0;
    while ( process_id > 0 )
    {
        process_id = process_id / 10 ;
        cnt++;
    }
    return ( cnt );
}

What is your system?

What is your compiler?

In gcc/linux, compile with -ggdb and run with gdb ./a.out, then type 'run', and when it crashes, type 'bt full' to show where it crashed.

Also: Listen to the warnings the compiler gives you. to wit:

definitions.h:10: warning: 'SRC_DIR' initialized and declared 'extern'
definitions.h:11: warning: 'LOG_DIR' initialized and declared 'extern'
definitions.h:12: warning: 'TMP_DIR' initialized and declared 'extern'
definitions.h:13: warning: 'ARCH_DIR' initialized and declared 'extern'
definitions.h:16: warning: 'LOG_NAME' initialized and declared 'extern'
definitions.h:17: warning: 'FIELD_SEP' initialized and declared 'extern'
definitions.h:18: warning: 'LOG_EXT' initialized and declared 'extern'
definitions.h:19: warning: 'TMP_EXT' initialized and declared 'extern'
definitions.h:20: warning: 'TRG_EXT' initialized and declared 'extern'
definitions.h:21: warning: 'ARCH_EXT' initialized and declared 'extern'
definitions.h:22: warning: 'DIR_SEP' initialized and declared 'extern'
port.c: In function 'main':
port.c:80: warning: format '%s' expects type 'char *', but argument 2 has type 'char **'
port.c:14: warning: unused variable 'target_stream'

header files don't work that way, and extern doesn't work that way. You either want to do

#define SRC_DIR "/home/hhulaman/1516/source/"

or

extern char * SRC_DIR;

with an accompanying

#include "definitions.h"
char *SRC_DIR="/home/hhulaman/1516/source/";

in definitions.c. This prevents the variable from being redefined 19 times if it's included in 19 seperate C files.

Better yet, make them constant, so you can't overwrite them accidentally:

extern const char const * SRC_DIR;

Hi ,
OS : HP-UX

compiler : gcc

Regards,
Kiran

Since you have gcc, do you have gdb? Or could you install it?