C指针分段故障崩溃

时间:2013-01-31 23:04:19

标签: c segmentation-fault

// Struct for Country Data
typedef struct
{
    char name[50];          // Country name
    char code[3];           // Country code
    int population;         // Country Population
    double lifeExp;         // Country Life expectancy  

}   CountryData;

// Struct for Dir File
typedef struct
{
    char code[50];
    int offSet;

}   DirData;

// Function Declarations
void fillCountryStructs(CountryData **dataPtr, int nLines, int fd);
void fillDirectoryStructs(CountryData **dataPtr, DirData **director, int nLines,int fd2);
void sortStructs(DirData **director, int nLines);
int verifyString(char *s1, char *s2);

// Main Function
// - This function starts the program, get the number of lines as a 
//   parameter, fills the structs and writes the data to the Country
//   File and the Directory file.
int main(int argc, char *argv[])        // Always remember to pass an argument while executing
{
    // Some variables
    int nLines;             // The number of lines
    char *pEnd;             // For String functions
    FILE *Fin,*Fout;        // File pointers
    int fd; 
    int fd2;
    nLines = strtod(argv[1], &pEnd); 
    CountryData **countryDataPtr;   // Array of structs
    CountryData **tempStruct;
    DirData **director;
    char buffer[15];    

    // Allocate memory for the struct pointers
    countryDataPtr = calloc(nLines, sizeof(CountryData*));
    director = calloc(nLines, sizeof(DirData*));
    // File Stream for "AllCountries.dat"
    if((fd = open("AllCountries.dat", O_RDWR|O_CREAT)) ==-1)
        err_sys("File not found...\n");
    // File Stream for "RandomStruct.bin"
    if ((fd2 = open("RandomStruct.bin",O_RDWR|O_CREAT)) == -1) 
        err_sys("Failed to open binary\n");

    // Filling the Country stucts
    fillCountryStructs(countryDataPtr, nLines, fd);

    close (fd);
    //fclose(Fin);                                      // Closing the file "AllCountries.dat"
    // Writing Binary File
    write(fd2, (countryDataPtr[0]->name[0]), sizeof(CountryData));

    int c=0;
    int n=0;
    int counter=0;
    int tempn=0;
    for (c=0;c<nLines;c++)
    {    
    write(fd2, (countryDataPtr[c]->name),50);

    write(fd2, (countryDataPtr[c]->code),4);


    sprintf(buffer, "%d", countryDataPtr[c]->population); // Function from String.h
    n = strlen(buffer);
    write(fd2, buffer, n);

    if (n<15)
    {
    for (counter=0;counter<(15-n);counter++)
    {
    write(fd2," ",1);
    }
    }
    //printf("n: %i n-15: %i\n",n,(15-n));

    //sprintf(buffer, "%0.1f", countryDataPtr[c]->lifeExp); // Function from String.h
    //n=((int)(countryDataPtr[c]->lifeExp));

    tempn=((int)(countryDataPtr[c]->lifeExp));

    sprintf(buffer, "%d", tempn); // Function from String.h
    n = strlen(buffer);
    write(fd2, buffer,n);
    write(fd2,"\n",1);
}
    close (fd2);

        printf("prueba\n");
    //fclose(Fout);
    printf("RandomStruct.bin written Sucessfully\n");

    // Filling the Directory File
    // File Stream for "RandomStructDir.dir"

    if ((fd2 = open("RandomStructDir.dir",O_RDWR|O_TRUNC)) != -1) 
        err_sys("Failed to open binary\n");
    printf("holla0\n");


    fillDirectoryStructs(countryDataPtr, director, nLines, fd2);


    printf("holla\n");
    sortStructs(director, nLines);                                  // Sorting the structs
    printf("holla2\n");
    // Write the number of lines in the FIRST LINE
    // of the Directory File
    write(fd2, &nLines, sizeof nLines);
    // Writing Directory File after the number of lines was written

    //write(fd2,(director[0]->code[0]), sizeof(DirData));

    for (c=0;c<nLines;c++)
    {    
        write(fd2, (director[c]->code),4);
    }

    close (fd2);
    //fclose(Fout);
    printf("RandomStructDir.dir written Sucessfully\n\n");

    exit(0);
}

// Filling the Country structs
// - This function extracts the data from the file using strtok 
//   and fills all the structs with their corresponding values.
void fillCountryStructs(CountryData **dataPtr, int nLines, int fd)
{
    int curLine = 0;        // Current line
    int index = 0;          // The index
    char buf[BUFSIZE];      // The Buffer with the size of BUFSIZE
    char *tok;              // Token
    char *pEnd;             // For the String functions
        char ch = 'a'; // The temp character
    int temPop;
    double temLifeExp;  
    int num=0;

    for(curLine = 0; curLine < nLines; curLine++)
    {
       // Reading each line
    dataPtr[curLine] = (CountryData *)calloc(1, sizeof(CountryData));
    index = 0;
    do
    {
    read(fd, &ch, 1);
    buf[index++] = ch;
    }
    while(ch != '\n');

        // Strtoking...
        tok = strtok(buf, ",\n");

        index = 1;
        while(tok != NULL)
        {
            tok = strtok(NULL, ",\n");

            // Get the Country Code
            if(index == 1)
            {
                strcpy(dataPtr[curLine]->code, tok);        // Copying code to the struct
             //write(fd2, (tok), sizeof(CountryData[0]));
            }
            // Get the Country Name
            if(index == 2)
            {
                strcpy(dataPtr[curLine]->name, tok);        // Copying name to the struct
          //write(fd2, (tok), sizeof(CountryData));
            }
            // Get the Country Population
            if(index == 7)
            {
                temPop = (int)strtol(tok, &pEnd, 10);
                dataPtr[curLine]->population = temPop;      // Copying population to the struct
            }
            // Get the Country Life expectancy
            if(index == 8)
            {
             num=countchar(tok);
          printf ("The number of characters entered is %d\n", num);
          printf ("The character entered is %s\n",tok);
                temLifeExp = strtod(tok, &pEnd);
                dataPtr[curLine]->lifeExp = temLifeExp;     // Copying life expectancy to the struct
            }
            index++;
        }
    }
}


int countchar (char list[])
{
        int i, count = 0;
        for (i = 0; list[i] != '\0'; i++)
        count++;
        return (count);
}



// Filling the Directory Structs
// - This function fills the directory with the offset
void fillDirectoryStructs(CountryData **dataPtr, DirData **director, int nLines, int fd2)
{

    int i = 0;
    for(i = 0; i < nLines; i++)
    {
        strcpy(director[i]->code, dataPtr[i]->code);      //It crashes in this Line
        director[i]->offSet = 72 * (i);     
    }   

}

// Sorting the Dir Structs
// - This function sorts the Directory Structs.
void sortStructs(DirData **director, int nLines)
{

    int maxNumber;
    int i;
    DirData **temp;
    temp = calloc(1, sizeof(DirData*));

    // Sorting the array of pointers!
    for(maxNumber = nLines - 1; maxNumber > 0; maxNumber--)
    {
        for(i = 0; i < maxNumber; i++)
        {
            if((verifyString(director[i]->code, director[i+1]->code)) == 1)
            {
                temp[0] = director[i];
                director[i] = director[i+1];
                director[i+1] = temp[0];
            }           
        }           
    }
}

// Veryfying the strings
// - This function compares two strings and return a specific value
//   accordingly.
int verifyString(char *s1, char *s2)
{
    int i;
    if(strcmp(s1,s2) == 0)
        return(0);          // They are equal

    for(i = 0; s1[i] != 0; i++)
    {
        if(s1[i] > s2[i])
            return(1);              // s1 is greater
        else if(s1[i] < s2[i])
            return(2);              // s2 is greater
    }

    return (2); // s2 is greater
}

所以这是我的代码由于某种原因,当我调用此方法时它会崩溃:

void fillDirectoryStructs(CountryData **dataPtr, DirData **director, int nLines, int fd2) ...

崩溃的确切行:

strcpy(director[i]->code, dataPtr[i]->code);    <-here

它必须是关于指针的东西或者我不知道,我正在尝试将右侧的内容复制到左侧的结构中。我打印dataPtr[0]->code并显示正确的值。

1 个答案:

答案 0 :(得分:1)

    strcpy(director[i]->code, dataPtr[i]->code);      //It crashes in this Line        

此时,director[i]并未指出任何内容。您需要一个director[i] = calloc(...行,就像在fillCountryStructs中一样。