簡體   English   中英

C中的分段錯誤主要但不是我的功能

[英]Segmentation Fault in C. Works in main but not my function

我正在嘗試創建一個程序,它將檢查用戶輸入文件的名稱,並查看文件中有多少次出現。 但是在我的getrawdata函數中,我一直遇到分段錯誤。

這是代碼:

struct NameRecord{ // Holds all the name information
    int year;
    char name [31];
    int frequency;
};


void allCaps(char s[]){ //Capitalizes all of the characters of s
    int i=0;
    while (s[i])
        {
            s[i] = toupper(s[i]);
            i++;
        }
    printf("The name entered is now in all caps! %s", s);
}

int getRawData1(FILE* male, struct NameRecord records[], int currSize){
    int readResult;
    printf("The current size is %d", currSize);
    readResult=fscanf(&*male, "%d", &records[currSize].year);
}
//Main
int main (){
    char name [31];
    FILE *male;
    FILE *female;
    int size = 0;
    //Opening files
    male = fopen("malebabynames.csv", "r"); //Dont leave in home directory 
    female = fopen("femalebabynames.csv", "r");
    struct NameRecord records[160000];

    if ( male==NULL){
        printf ("Error: the data file does not exist");
    }
    if ( female==NULL){
        printf ("Error: the data file does not exist");
    }

    size = getRawData1(male, records, size);
    //Output   
    printf("Please enter a name: ");
    scanf("%s", name);
    allCaps(name);
}

修改后的代碼 - 仍然崩潰

Codepad的原始版本; 這個版本的SSCCE'd

#include <stdio.h>

struct NameRecord
{
    int year;
    char name[31];
    int frequency;
};
struct NameRecord records[160000];

void allCaps(char s[])
{
    int i = 0;
    while (s[i])
    {
        s[i] = toupper(s[i]);
        i++;
    }
    printf("The name entered is now in all caps! %s", s);
}

int getRawData1(FILE *male, struct NameRecord records[], int currSize)
{
    int readResult;
    printf("The current size is %d", currSize);
    readResult = fscanf(male, "%d,%[^,],%d\n", &records[currSize].year,
                        records[currSize].name, records[currSize].frequency);

    while (readResult == 3)
    {
        currSize++;
        readResult = fscanf(male, "%d,%[^,],%d\n", &records[currSize].year,
                            records[currSize].name, &records[currSize].frequency);
    }
    printf("The size of the array is %d", currSize);
    return currSize;
}

int main()
{
    char name[31];
    FILE *male;
    FILE *female;
    int size = 0;

    male = fopen("malebabynames.csv", "r");
    female = fopen("femalebabynames.csv", "r");
    int i = 0;
    int readResult;
    if (male == NULL)
    {
        printf("Error: the data file does not exist");
    }
    if (female == NULL)
    {
        printf("Error: the data file does not exist");
    }
    getRawData1(male, records, size);

    printf("Welcome to the Name Popularity Checker \n====================================== \n");
    printf("Please enter a name: ");
    scanf("%s", name);
    allCaps(name);
}

這實際上在啟動時因為這條線路在VS2012中崩潰了:

struct NameRecord records[160000];

我想你可能會超出你的可用堆棧空間。 至少這對我來說! 這個數字需要這么高嗎? 你可以根據你從文件中讀到的內容動態分配嗎?

考慮下面Barmar的建議,你可以這樣做來解決它(如果你真的需要160k記錄的靜態分配):

struct NameRecord{ // Holds all the name information
  int year;
  char name [31];
  int frequency;
};

NameRecord records[160000];

換句話說,使它成為全局變量而不是堆棧上的變量。

更新:另外,使用Jonathan Leffler的建議,您可以確保正確打開文件。 如果文件未正確打開,您當前只是打印一條消息,但如果是這種情況則不應繼續執行。

if (male == NULL)
{
    printf("Error: the data file does not exist");
    return EXIT_FAILURE;
}
if (female == NULL)
{
    printf("Error: the data file does not exist");
    return EXIT_FAILURE;
}

注意編譯器警告。 如果您沒有收到編譯器警告,請將它們打開; 如果您仍然沒有收到編譯器警告,請獲得更好的編譯器。

$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition x.c -o x
x.c: In function ‘getRawData1’:
x.c:30:25: warning: format ‘%d’ expects argument of type ‘int *’, but argument 5 has type ‘int’ [-Wformat=]
                         records[currSize].name, records[currSize].frequency);
                         ^
x.c:30:25: warning: format ‘%d’ expects argument of type ‘int *’, but argument 5 has type ‘int’ [-Wformat=]
$

你錯過了一個&

                         records[currSize].name, &records[currSize].frequency);

(我已經添加了#include <ctype.h>並在函數前放置static來平息編譯器的其他警告。)


您還應該重新設計getRawData1()的接口:

int getRawData1(FILE *fp, struct NameRecord records[], int maxSize)
{
    int readResult;
    printf("The maximum size is %d", maxSize);
    int currSize = 0;

    while (currSize < maxSize &&
           (readResult = fscanf(fp, "%d,%[^,],%d\n", &records[currSize].year,
                                records[currSize].name, &records[currSize].frequency)) == 3)
        currSize++;

    printf("The amount of data in the array is %d", currSize);
    return currSize;
}

所謂的:

num_male_names = getRawData1(male, records, 160000);

如果文件中有超過160,000條記錄,這可以防止緩沖區溢出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM