Segmentation fault in fopen when in write mode.


 
Thread Tools Search this Thread
Top Forums Programming Segmentation fault in fopen when in write mode.
# 1  
Old 07-16-2012
Segmentation fault in fopen when in write mode.

Hi All,

Although this code is quite long but it does not require one to understand the logic of the code. I am trying to run this code on my Linux machine using gcc. But when this line is executed:
Code:
output_pointer = fopen ( file_name , "w" );

I get segmentation fault. I've been breaking my head Smilie for a long time on this but with no clues. Exact error retrieved using gdb

Code:
Program received signal SIGSEGV, Segmentation fault.
0x00000031f4a7873e in _int_malloc () from /lib64/libc.so.6

This is my code:

Code:
#define _GNU_SOURCE
#define _BSD_SOURCE

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include <search.h>

#define NUMBER_OF_FILES 300000
#define LENGTH_OF_FILE 7617230 //number of records in the file

unsigned long int number_of_lines ( FILE * );
void file_name_generator ( unsigned long int , char * , char * );
char * itoa ( int , char * );
char * reverse ( char [] );
void file_names ( unsigned int ,char * , char * );
char * chomp ( char * );

int32_t main ( int32_t argc , char ** argv )
{
    FILE *output_pointer = NULL;
    FILE *bigram_counts = NULL;
    FILE *input_file = NULL;
    FILE *bigram_words = NULL;

    unsigned long int i = 0;
    unsigned long int number_of_words = 0;
    char *file_name = NULL;
    char **words_from_webpage = NULL;
    unsigned long int j = 0;
    unsigned long int *store_values = NULL;
    char **bigram_words_array = NULL;
    unsigned long int *bigram_counts_array = NULL;
    unsigned long int array_index = 0;
    char *str = NULL;

    char *line = NULL;
    size_t len = 0;
    ssize_t read = 0;
    
    bigram_words_array = ( char ** ) malloc ( LENGTH_OF_FILE * sizeof ( char * ) );
    if ( bigram_words_array == NULL )
    {
      fprintf ( stderr , "malloc() memory allocation failure\n" );
    }
    
    for ( i = 0 ; i < LENGTH_OF_FILE ; i ++ )
    {
        bigram_words_array [ i ] = ( char * ) malloc ( 50 * sizeof ( char ) );
        if ( bigram_words_array  [ i ] == NULL )
        {
            fprintf ( stderr , "malloc() memory allocation failure\n" );
        }
    }


    bigram_counts_array = ( unsigned long int * ) malloc ( LENGTH_OF_FILE * sizeof ( unsigned long int ) );
    if ( bigram_counts_array == NULL )
    {
      fprintf ( stderr , "malloc() memory allocation failure\n" );
    }

    str = ( char * ) malloc ( 4 * sizeof ( char ) );
    if ( str == NULL )
    {
        fprintf ( stderr , "malloc() memory allocation failure\n" );
    }

    ENTRY e , *ep;

    bigram_counts = fopen ( "counts.dat" , "r" );
    if ( bigram_counts == NULL )
    {
        fprintf ( stderr , "file read error\n" );
    }
    
    bigram_words = fopen ( "bigrams.dat" , "r" );
    if ( bigram_words == NULL )
    {
      fprintf ( stderr , "file read error\n" );
    }

    file_name = ( char * ) malloc ( 300 * sizeof ( char ) );
    if ( file_name == NULL )
    {
        fprintf ( stderr , "malloc() memory allocation failure\n" );
    }
    
    while ( !feof ( bigram_words ) )
    {
        while ( ( read = getline ( &line , &len , bigram_words ) ) != -1 )
            {
                line = chomp ( line );//this removes newline character
                strcpy ( bigram_words_array [ j ] , line );
                if ( j <= LENGTH_OF_FILE )
                {
                    j ++;
                }
            }
    }
    
    j = 0;
    
    while ( !feof ( bigram_counts ) )
    {
      fscanf ( bigram_counts , "%ld\n" , &bigram_counts_array [ j ++ ] );
    }
    j = 0;


    if ( line )
    {
        free ( line );
    }
        
    hcreate ( LENGTH_OF_FILE ); //building the hash table
    for ( i = 0 ; i < LENGTH_OF_FILE ; i ++ )
    {
        e.key = bigram_words_array [ i ];
        e.data = ( void * ) i;
        ep = hsearch ( e , ENTER );
        if ( ep == NULL )
        {
            fprintf ( stderr , "hash table entry failed\n" );
        }
    }

    fclose ( bigram_counts );
    fclose ( bigram_words );

    for ( i = 0 ; i < NUMBER_OF_FILES ; i ++ ) //this will iterate through all the files in the directory
    {
        file_name_generator ( ( i + 1 ) , file_name , str ); //this generates the file name of the file to be read
        memset ( str , 0 , strlen ( str ) );
        input_file = fopen ( file_name , "r" );
        if ( input_file == NULL )
        {
            memset ( file_name , 0 , strlen ( file_name ) );
            fclose ( input_file );
            continue;
        }

        number_of_words = number_of_lines ( input_file ); //computes the number of words in the data file
        store_values = ( unsigned long int * ) malloc ( number_of_words * sizeof ( unsigned long int ) ); this array will store all the numerical values corresponding to the words
        if ( store_values == NULL )
        {
            fprintf ( stderr , "malloc() memory allocation failure\n" );
        }

        words_from_webpage = ( char ** ) malloc ( number_of_words * sizeof ( char * ) ); //this read the data file consising of words each word in newline
        if ( words_from_webpage == NULL )
        {
            fprintf ( stderr , "malloc() memory allocation failure in words_from_webpage\n" );
        }

        for ( j = 0 ; j < number_of_words ; j ++ )
        {
            words_from_webpage [ j ] = ( char * ) malloc ( 20 * sizeof ( char ) );
            if ( words_from_webpage [ j ] == NULL )
            {
                fprintf ( stderr , "malloc() memory allocation failure\n" );
            }
        }

        j = 0;
        rewind ( input_file );

        while ( !feof ( input_file ) )
        {
            while ( ( read = getline ( &line , &len , input_file ) ) != -1 )
            {
                line = chomp ( line );
                strcpy ( words_from_webpage [ j ] , line );
                if ( j <= number_of_words )
                {
                    j ++;
                }
            }
        }

        if ( line )
        {
            free ( line );
        }

        for ( j = 0 ; j < number_of_words ; j ++ )
        {
            e.key = words_from_webpage [ j ];
            ep = hsearch ( e , FIND ); //find the word in the hash table and get the index of the word from the word list file
            array_index = ( unsigned long int ) ( ep -> data );
             * ( store_values + j ) = bigram_counts_array [ array_index ];
        }
        
        memset ( file_name , 0 , strlen ( file_name ) );

        file_names ( ( i + 1 ) , file_name , str ); //get the file path of the file to be written.
        
        output_pointer = fopen ( file_name , "w" ); //THIS IS WHERE THE PROBLEM OCCURS
        if ( output_pointer == NULL )
        {
            fprintf ( stderr , "file write error\n" );
        }

        j = 0;
        while ( j < number_of_words )
        {
            fprintf ( output_pointer , "%ld\n" , store_values [ j ] + 1 );
            j ++;
        }
        fclose ( output_pointer );

        memset ( store_values , 0 , sizeof ( store_values ) );
        memset ( file_name , 0 , strlen ( file_name ) );
        memset ( str , 0 , strlen ( str ) );

        fclose ( input_file );
        for ( j = 0 ; j < number_of_words ; j ++ )
        {
            words_from_webpage [ j ] = '\0';
        }
        memset ( words_from_webpage , 0 , strlen ( words_from_webpage ) );
    }


    free ( file_name );
    free ( str );

    for ( j = 0 ; j < number_of_words ; j ++ )
    {
        free ( words_from_webpage [ j ] );
    }
    free ( words_from_webpage );

    for ( j = 0 ; i < LENGTH_OF_FILE ; j ++ )
    {
        free ( bigram_words_array [ j ] );
    }
    free ( bigram_words_array );

    free ( bigram_counts_array );

    fclose ( bigram_counts );
    fclose ( bigram_words );

    return ( EXIT_SUCCESS );
}


char *chomp ( char * word )
{
    int32_t word_length = 0;
    word_length = strlen ( word );
    if ( word [ word_length - 1 ] == '\n' )
    {
        word [ word_length - 1 ] = '\0';
    }
    return ( word );
}


void file_names ( unsigned int i , char * file_name , char * str )
{
    char common_path[] = {"/data/scores/"};

    str = itoa ( i  , str );
    strcat ( file_name , common_path );
    strcat ( str , ".dat" );
    strcat ( file_name , str );
}


unsigned long int number_of_lines ( FILE *input_file )
{
    char ch;
    unsigned long int number_of_words = 0;

    while  ( ! ( feof ( input_file ) ) )
    {
        ch = fgetc ( input_file );
        if ( ch == '\n' )
        {
            number_of_words++;
        }
    }
    return ( number_of_words );
}


void file_name_generator ( unsigned long int i , char * file_name , char *str )
{
    strcat ( file_name , "/data/files/" );
    str = itoa ( i , str );
    strcat ( file_name, str );
    strcat ( file_name , ".dat" );
}


char * itoa ( int n , char * s )
{
     int i, sign;
 
     if ( ( sign = n ) < 0 )  /* record sign */
         n = -n;          /* make n positive */
     i = 0;
     do {       /* generate digits in reverse order */
         s [ i++ ] = n % 10 + '0';   /* get next digit */
     } while ( ( n /= 10 ) > 0 );     /* delete it */
     if ( sign < 0 )
         s [ i++ ] = '-';
     s [ i ] = '\0';
     reverse ( s );
    return ( s );
}


char * reverse ( char s [ ] )
{
     int i, j;
     char c;
 
    for ( i = 0, j = strlen ( s ) - 1; i < j; i ++, j -- ) 
    {
             c = s [ i ];
             s [ i ] = s [ j ];
             s [ j ] = c;
         }
    return ( s );
}

# 2  
Old 07-16-2012
You have corrupted the file_name pointer. (example) This means that the filename filename originally lived at address 0x006000, but your code changed it so filename now references 0x005ff80. Or some other invalid address, like NULL.

To diagnose:
put this in your code:
Code:
printf("file_name reference on line %d = %p\n", __LINE__, file_name);

just before EVERY line that has file_name in it.
This User Gave Thanks to jim mcnamara For This Post:
# 3  
Old 07-16-2012
Hello, shoaibjameel123:

On an unrelated note, I'm curious about something. I've noticed in your last couple of C threads that your main() prototype is using fixed-width integer types. Why are you using int32_t instead of plain int?

On a typical server or desktop system, int32_t is almost certainly a typedef (or a typedef of a typedef) of int anyway, so it doesn't cause a problem (at least until we move to 256 bit systems Smilie). All joking aside, it seems to me an unnecessarily restrictive choice.

Regards,
Alister

Last edited by alister; 07-16-2012 at 11:53 AM.. Reason: typo/grammar
# 4  
Old 07-16-2012
Great thanks. Let me try this, if things work fine, I'll put my working code here for others to learn.

---------- Post updated at 10:56 PM ---------- Previous update was at 10:49 PM ----------

Hello, Alister,
There are several machines in my computing laboratory some of which are 64 bit machines and others 32 bit. I do not have a fixed machine to work on, so sometimes I may use 64bit machine and sometimes 32bit. Just to keep my code portable, I use int32_t.

But now I am curious to know. Is my logic described in the above paragraph correct? Or I am fundamentally mistaken about the machine architectures and the way I use int32_t?
# 5  
Old 07-16-2012
You are mistaken. This use of a fixed-width type makes your code less portable. However, this mistake is unlikely to cause a problem so long as you work with the widely-available 32 and 64 bit platforms.

As I recall, C requires main() to return int or void. If main() takes any arguments, argc must be an int.

On UNIX and Windows NT, on both 32-bit and 64-bit platforms, the data models specify a 32 bit int. On such platforms, int32_t is implemented using a typedef (or two) which essentially aliases int32_t to int, which is what the standard requires. So long as this is the case, the compiler is happy.

But, what would happen if you tried to compile that on a 16 bit machine? On a 16 bit machine, int32_t may be implemented with long. If that's the case, your code won't compile (if it does, there will likely be serious problems). A similar problem could arise if this code were compiled on a 64 bit architecture with 64 bit ints.

Regards,
Alister
This User Gave Thanks to alister For This Post:
# 6  
Old 07-16-2012
It's more portable in one sense, at least. If it compiles at all, you'll get 32-bit datatypes where you want them.

So, use them if you need a 32-bit data type, but only if you need a 32-bit data type.
This User Gave Thanks to Corona688 For This Post:
# 7  
Old 07-16-2012
I would agree with Corona688. I could not express this very well in my reply. My objective is to keep the values to 32bit ints only.

Alister has got the fundamentals right. yes, int32_t is typedef'ed to int. But I also recall that if on a 32bit architecture, one has to use a 64bit int, then one needs to explicitly specify int64_t.

---------- Post updated at 10:12 AM ---------- Previous update was at 09:48 AM ----------

I did try to run the code with the line:
Code:
printf("file_name reference on line %d = %p\n", __LINE__, file_name);

I get this as outputs,which makes me feel that file_name is not getting corrupted. Here is the result when I execute the code:

Code:
file_name reference on line 88 = (nil)
file_name reference on line 140 = 0x1d6ed830
file_name reference on line 305 = 0x1d6ed830
file_name reference on line 202 = 0x1d6ed830
file_name reference on line 206 = 0x1d6ed830
file_name reference on line 276 = 0x1d6ed830
file_name reference on line 209 = 0x1d6ed830
Segmentation fault (core dumped)

I even tested with this but still the program fails to execute:

Code:
output_pointer = fopen ( "1.dat" , "w" );

Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Programming

C. To segmentation fault or not to segmentation fault, that is the question.

Oddities with gcc, 2.95.3 for the AMIGA and 4.2.1 for MY current OSX 10.14.1... I am creating a basic calculator for the AMIGA ADE *NIX emulator in C as it does not have one. Below are two very condensed snippets of which I have added the results inside the each code section. IMPORTANT!... (11 Replies)
Discussion started by: wisecracker
11 Replies

2. Shell Programming and Scripting

Count Segmentation fault and write to the file

Hi everyone Need to get version of npm application that have several output like this: root: nmp -version 10 root: nmp -version 10 root: nmp-new -version 3.1 root: nmp-old -version Segmentation fault count them , after that write to the file like this: 10 2 3.1 1 (1 Reply)
Discussion started by: indeed_1
1 Replies

3. Solaris

Segmentation fault

Hi Guys, I just installed and booted a zone called testzone. When I logged in remotely and tried changing to root user I get this error: "Segmentation fault" Can someone please help me resolve this? Thanks alot (2 Replies)
Discussion started by: cjashu
2 Replies

4. Programming

Using gdb, ignore beginning segmentation fault until reproduce environment segmentation fault

I use a binary name (ie polo) it gets some parameter , so for debugging normally i do this : i wrote script for watchdog my app (polo) and check every second if it's not running then start it , the problem is , if my app , remain in state of segmentation fault for a while (ie 15 ... (6 Replies)
Discussion started by: pooyair
6 Replies

5. UNIX for Dummies Questions & Answers

Segmentation fault

#include<stdio.h> #include<malloc.h> #include<unistd.h> #include<stdlib.h> void *start_1(void *argv) { printf("thread 0x%x\n",(unsigned int)pthread_self()); pthread_exit((void*)1); } void *start_2(void *argv) { printf("thread 0x%x\n",(unsigned int)pthread_self()); return (void*)2; }... (2 Replies)
Discussion started by: vincent__tse
2 Replies

6. Programming

Segmentation fault.

I'm getting a segmentation fault. I'm new to Linux programming. Thanks so much for all of your input.:eek: #include </usr/include/mysql++/mysql++.h> #include <stdio.h> #include <iostream> #include <sstream> #include <string.h> using namespace std; int outputToImport(const char*... (1 Reply)
Discussion started by: sepoto
1 Replies

7. Programming

segmentation fault

Hi, I am having this segmentation fault not in the following program, bt. in my lab program . My lab program is horrible long so cannot post it here bt. I am using the following logic in my program which is giving the segmentation fault. Bt. if I run this sample program as it is it dosen't give... (3 Replies)
Discussion started by: mind@work
3 Replies

8. AIX

Segmentation fault

Hi , During execution a backup binary i get following error "Program error 11 (Segmentation fault), saving core file in '/usr/datatools" Riyaz (2 Replies)
Discussion started by: rshaikh
2 Replies

9. Programming

Hi! segmentation fault

I have written a program which takes a directory as command line arguments and displays all the dir and files in it. I don't know why I have a problem with the /etc directory.It displays all the directories and files untill it reaches a sub directory called peers which is in /etc/ppp/peers.the... (4 Replies)
Discussion started by: vijlak
4 Replies

10. Programming

segmentation fault

sometimes for this code i get a segmentation fault for codes llike this : int main{ int * a= 0; int b; a = (int*)malloc(sizeof(int)); ///some code using these variable but no freeing of a if(a){ free(a); a = 0; } return... (3 Replies)
Discussion started by: wojtyla
3 Replies
Login or Register to Ask a Question