[英]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);
}
#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.