Domanda

in my program, I provide a directory which contains text files. Each of the text files contain a few hundred lines in the following format

Username,Password,BloodType,Domain,Number

I then create a thread for each file in the directory which will merge-sort(by number) these lines into the array char* text_lines[6000];

I can't figure out why I'm getting a segmentation fault because I'm getting different output on every run.

Heres my code:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>

void store_line(char* line);
void* my_merge_sort(void* file);

char** text_lines;

int main(int argc, char* argv[])
{

    if(argc != 2)
    {
        fprintf(stderr, "usage: ./coolsort <directory>\n");
    }
    else
    {
        text_lines = malloc(6000 * sizeof(char*));
        DIR* the_directory;
        int filecount = 0;
        struct dirent* directory_files[50];
        if((the_directory = opendir(argv[1])) != NULL)
        {
            //make a list of the files in the directory
            while((directory_files[filecount++] = readdir(the_directory))) ;
            filecount--;

            //<<<DEBUGGING INFO>
            int i;
            fprintf(stderr,"there are %i files in %s:\n", filecount, argv[1]);
            for(i = 0; i < filecount; i++)
            {
                fprintf(stderr, "%s\n",directory_files[i]->d_name);
            }
            char cwd[512];
            chdir(argv[1]);
            getcwd(cwd, sizeof(cwd));
            fprintf(stderr, "the CWD is:  %s\n", cwd);
            //<DEBUGGING INFO>>>

            //lets start some threads
            pthread_t threads[filecount-2];
            int x = 0;
            for(i = 0; i < (filecount); i++ )
            {
                if (!strcmp (directory_files[i]->d_name, "."))
                    continue;
                if (!strcmp (directory_files[i]->d_name, ".."))    
                    continue;
                pthread_create(&threads[x++], NULL, my_merge_sort, (void*)directory_files[i]->d_name);
            }
            //do stuff here

            //
        }
        else
        {
            fprintf(stderr, "Failed to open directory: %s\n", argv[1]);
        }
    }
}

void* my_merge_sort(void* file)
{
    fprintf(stderr, "We got into the function!\n");
    FILE* fp = fopen(file, "r");
    char* buffer;
    char* line;
    char delim[2] = "\n";
    int numbytes;

    //minimize I/O's by reading the entire file into memory;
    fseek(fp, 0L, SEEK_END);
    numbytes = ftell(fp);
    fseek(fp, 0L, SEEK_SET);
    buffer = (char*)calloc(numbytes, sizeof(char));
    fread(buffer, sizeof(char), numbytes, fp);
    fclose(fp); 

    //now read the buffer by '\n' delimiters
    line = strtok(buffer, delim);
    fprintf(stderr, "Heres the while loop\n");
    while(line != NULL)
    {
        store_line(line);
        line = strtok(buffer, NULL);
    }
    free(buffer);
}

void store_line(char* line)
{   
    //extract the ID.no, which is the fifth comma-seperated-token. 
    char delim[] = ",";
    char* buff;
    int id;
    int i;
    strtok(line, delim);
    for(i = 0; i < 3; i++)
    {
        strtok(line, NULL);
    }
    buff = strtok(line, NULL);
    id = atoi(buff);

    //copy the line to text_lines[id]
    memcpy(text_lines[id], line, strlen(line));
}

edit: I checked to make sure that it would fit into the initial array, and found that the highest ID is only 3000;

È stato utile?

Soluzione

  1. You use of strtok() is wrong:

    line = strtok(buffer, NULL);
    

    should be

    line = strtok(NULL, delim);
    

    Another mistakes should be fixed similarly.

  2. The elements of text_lines are uninitialized:

    text_lines = malloc(6000 * sizeof(char*));
    

    this allocated 6000 pointers to char, but none of these pointers are initialized.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top