Seg Fault Error :11 Known lines with Error
Seg Fault Error :11 Known lines with Error
我在这段代码中有段错误,但我不明白为什么。有人可以解释我做错了什么吗?
我已经评论了我需要在此功能中做的事情列表。我以为我做对了,但是当我把它打印出来时,却发现实际上发生了完全不同的事情。
void analyze_file(FILE *file, struct climate_info **states, int num_states) {
const int line_sz = 100;
char line[line_sz];
int currentStates = countStates(states);
while (fgets(line, line_sz, file) != NULL)
{
char* foundCode = strtok(line, "\t");
int rankOfState = compareOrder(states, foundCode, currentStates);
if(rankOfState == -1)
{
states[currentStates] = (struct climate_info *) malloc(sizeof(struct climate_info) *num_states);
strcpy((states[currentStates]) -> code, foundCode);
states[currentStates] -> num_records=1;
char* currentTimeStamp = strtok(NULL, "\t");
unsigned long TIMESTAMP;
sscanf(currentTimeStamp,"%lu", &TIMESTAMP);
char* currentGeol = strtok(NULL, "\t");
long long GEOL;
sscanf(currentGeol,"%llu", &GEOL);
char* currentHumidity = strtok(NULL, "\t");
double HUMIDITY;
sscanf(currentHumidity, "%lf",&HUMIDITY);
char* currentSnow = strtok(NULL, "\t");
float SNOW;
sscanf(currentSnow, "%f", &SNOW);
char* currentCloud = strtok(NULL, "\t");
double CLOUD;
sscanf(currentCloud, "%lf",&CLOUD);
char* currentLightning = strtok(NULL, "\t");
float LIGHTNING;
sscanf(currentLightning, "%f", &LIGHTNING);
char* currentPressure = strtok(NULL,"\t");
double PRESSURE;
sscanf(currentPressure, "%lf", &PRESSURE);
char* currentTemp = strtok(NULL, "\t\n");
double TEMP;
sscanf(currentTemp, "%lf",&TEMP);
if (TEMP < states[currentStates]->lo_temp_reading || states[currentStates]->lo_temp_timestamp == 0)
{
states[currentStates]->lo_temp_reading = TEMP;
states[currentStates]->lo_temp_timestamp = TIMESTAMP;
}
if (TEMP > states[currentStates]->hi_temp_reading || states[currentStates]->hi_temp_timestamp == 0)
{
states[currentStates]->hi_temp_reading = TEMP;
states[currentStates]->hi_temp_timestamp = TIMESTAMP;
}
currentStates++;
}
else
{
(*(states +rankOfState))->num_records +=1;
char* currentTimeStamp = strtok(NULL, "\t");
unsigned long TIMESTAMP;
sscanf(currentTimeStamp,"%lu", &TIMESTAMP);
char* currentGeol = strtok(NULL, "\t");
(*(states +rankOfState))->hi_millitime += *currentGeol;
char* currentHumidity = strtok(NULL, "\t");
double HUMIDITY;
sscanf(currentHumidity, "%lf",&HUMIDITY);
(*(states +rankOfState))->humidity += HUMIDITY;
char* currentSnow = strtok(NULL, "\t");
float SNOW;
sscanf(currentSnow, "%f", &SNOW);
(*(states +rankOfState))->snow += SNOW;
char* currentCloud = strtok(NULL, "\t");
double CLOUD;
sscanf(currentCloud, "%lf",&CLOUD);
(*(states +rankOfState))->cloud += CLOUD;
char* currentLightning = strtok(NULL, "\t");
float LIGHTNING;
sscanf(currentLightning, "%f", &LIGHTNING);
(*(states +rankOfState))->lightning += LIGHTNING;
char* currentPressure = strtok(NULL,"\t");
double PRESSURE;
sscanf(currentPressure, "%lf", &PRESSURE);
(*(states +rankOfState))->pressure += PRESSURE;
char* currentTemp = strtok(NULL, "\t\n");
double TEMP;
sscanf(currentTemp, "%lf",&TEMP);
(*(states +rankOfState))->temperature += TEMP;
if (TEMP <= states[currentStates]->lo_temp_reading)
{
states[currentStates]->lo_temp_reading = TEMP;
states[currentStates]->lo_temp_timestamp = *currentTimeStamp;
}
else if (*currentTemp > states[currentStates]->hi_temp_reading)
{
states[currentStates]->hi_temp_reading = *currentTemp;
states[currentStates]->hi_temp_timestamp = *currentTimeStamp;
}
currentStates++;
}
}
}
如果我注释掉这些行,我的输出打印但是,它只分析一行。
if (TEMP <= states[currentStates]->lo_temp_reading)
{
states[currentStates]->lo_temp_reading = TEMP;
states[currentStates]->lo_temp_timestamp = *currentTimeStamp;
}
else if (*currentTemp > states[currentStates]->hi_temp_reading)
{
states[currentStates]->hi_temp_reading = *currentTemp;
states[currentStates]->hi_temp_timestamp = *currentTimeStamp;
}
这是我使用的辅助函数:
int compareOrder(struct climate_info **states, char codex[3], int currentStates) //returns the order of each state in the array
{
int order = 0;
while (order < currentStates) //while order is less than number of states analyzed
{
if(strcmp((states[order])->code, codex) == 0) //if the states is present
{
return order;
}
order++; //increment here to check every line for when to update state codes
}
return -1; //returns -1 the state is not prsent in struct
}
int countStates(struct climate_info **states) //function to count number of states present
{
int num = 0;
while(num < 50 && states[num] != NULL)
{
num++;
}
return num;
}
你的代码有很多问题,很遗憾,缺少很多信息,所以这个答案是基于假设的。
编辑: 好的,这部分在您对问题的最新编辑中已经过时了;仍然:建议的签名是优越的,因为它不依赖于硬编码的最大数组长度,您另外提供为 'magic number'...
首先,countStates
函数;我假设它看起来或多或少如下:
size_t countStates(struct climate_info** states)
{
struct climate_info** end = states;
while(*end)
++end;
return end - states;
}
现在的问题是您可以轻松地超出数组边界进行迭代,从而导致未定义的行为并可能已经在此函数中崩溃。要修复,总数组 size/length 以及:
size_t countStates(struct climate_info** states, size_t length)
{
struct climate_info** end = states;
while(length-- && *end)
++end;
return end - states;
}
然后我们进入实际的功能(不要怀疑更改formatting/syntax,如果不另外说明,它们是等价的-这些是我个人的喜好...):
// (size_t is more appropriate than int here...)
void analyze_file(FILE* file, struct climate_info* states[], size_t num_states)
{
const size_t line_sz = 100;
char line[line_sz];
size_t currentStates = countStates(states, num_states);
while (fgets(line, line_sz, file) != NULL)
{
char* foundCode = strtok(line, "\t");
int rankOfState = compareOrder(states, foundCode, currentStates);
if(rankOfState == -1)
{
// new states available at all?
if(currentStates == num_states)
{
// some appropriate error handling - need to decide you!
// for now, just returning from function:
return;
}
// just allocate one struct (assumption):
states[currentStates] = (struct climate_info *) malloc(sizeof(struct climate_info));
// always check the result of malloc!
if(!states[currentStates])
{
// allocation failed, no memory available on OS!!!
// some appropriate error handling - need to decide you!
// for now, just returning from function:
return;
}
// prefer strncpy to assure you don't copy past the end!
// sure, it will fill overdue bytes with 0, but still we are safer
// (assumption: climate_info contains an array!)
strncpy(states[currentStates]->code, foundCode, sizeof(states[currentStates]->code));
states[currentStates]->num_records = 1;
// ...
// now you created a new struct with malloc; be aware
// that memory is uninitialized and could contain *ANY*
// data, reading uninitialized memory is undefined behaviour!
//if (TEMP < states[currentStates]->lo_temp_reading || states[currentStates]->lo_temp_timestamp == 0)
//{
states[currentStates]->lo_temp_reading = TEMP;
// states[currentStates]->lo_temp_timestamp = TIMESTAMP;
//}
//if (TEMP > states[currentStates]->hi_temp_reading || states[currentStates]->hi_temp_timestamp == 0)
//{
states[currentStates]->hi_temp_reading = TEMP;
states[currentStates]->hi_temp_timestamp = TIMESTAMP;
//}
// (it's a new set anyway, so just set the values...)
currentStates++;
}
else
{
++states[rankOfState]->num_records; // just a little bit simpler...
// ...
states[rankOfState]->temperature += TEMP;
if (TEMP <= states[currentStates]->lo_temp_reading)
{
states[currentStates]->lo_temp_reading = TEMP;
states[currentStates]->lo_temp_timestamp = *currentTimeStamp;
}
// this should not have resulted in crash, but assign a bad value!
else if (TEMP /* *currentTemp */ > states[currentStates]->hi_temp_reading)
{
states[currentStates]->hi_temp_reading = TEMP /* *currentTemp */;
states[currentStates]->hi_temp_timestamp = *currentTimeStamp;
}
// same for timestamp in both branches: you don't want to assign first character of string,
// but the parsed value (e. g. 1012, if string was "1012", *... would deliver 49
// (ASCII code of character `1`; assuming you have ASCII compatible encoding)
// wrong in this branch: you did NOT add a new element
//currentStates++;
}
}
}
如前所述:这是基于我认为您正在尝试做的事情。如果我的假设是错误的,请发表评论...
我在这段代码中有段错误,但我不明白为什么。有人可以解释我做错了什么吗? 我已经评论了我需要在此功能中做的事情列表。我以为我做对了,但是当我把它打印出来时,却发现实际上发生了完全不同的事情。
void analyze_file(FILE *file, struct climate_info **states, int num_states) {
const int line_sz = 100;
char line[line_sz];
int currentStates = countStates(states);
while (fgets(line, line_sz, file) != NULL)
{
char* foundCode = strtok(line, "\t");
int rankOfState = compareOrder(states, foundCode, currentStates);
if(rankOfState == -1)
{
states[currentStates] = (struct climate_info *) malloc(sizeof(struct climate_info) *num_states);
strcpy((states[currentStates]) -> code, foundCode);
states[currentStates] -> num_records=1;
char* currentTimeStamp = strtok(NULL, "\t");
unsigned long TIMESTAMP;
sscanf(currentTimeStamp,"%lu", &TIMESTAMP);
char* currentGeol = strtok(NULL, "\t");
long long GEOL;
sscanf(currentGeol,"%llu", &GEOL);
char* currentHumidity = strtok(NULL, "\t");
double HUMIDITY;
sscanf(currentHumidity, "%lf",&HUMIDITY);
char* currentSnow = strtok(NULL, "\t");
float SNOW;
sscanf(currentSnow, "%f", &SNOW);
char* currentCloud = strtok(NULL, "\t");
double CLOUD;
sscanf(currentCloud, "%lf",&CLOUD);
char* currentLightning = strtok(NULL, "\t");
float LIGHTNING;
sscanf(currentLightning, "%f", &LIGHTNING);
char* currentPressure = strtok(NULL,"\t");
double PRESSURE;
sscanf(currentPressure, "%lf", &PRESSURE);
char* currentTemp = strtok(NULL, "\t\n");
double TEMP;
sscanf(currentTemp, "%lf",&TEMP);
if (TEMP < states[currentStates]->lo_temp_reading || states[currentStates]->lo_temp_timestamp == 0)
{
states[currentStates]->lo_temp_reading = TEMP;
states[currentStates]->lo_temp_timestamp = TIMESTAMP;
}
if (TEMP > states[currentStates]->hi_temp_reading || states[currentStates]->hi_temp_timestamp == 0)
{
states[currentStates]->hi_temp_reading = TEMP;
states[currentStates]->hi_temp_timestamp = TIMESTAMP;
}
currentStates++;
}
else
{
(*(states +rankOfState))->num_records +=1;
char* currentTimeStamp = strtok(NULL, "\t");
unsigned long TIMESTAMP;
sscanf(currentTimeStamp,"%lu", &TIMESTAMP);
char* currentGeol = strtok(NULL, "\t");
(*(states +rankOfState))->hi_millitime += *currentGeol;
char* currentHumidity = strtok(NULL, "\t");
double HUMIDITY;
sscanf(currentHumidity, "%lf",&HUMIDITY);
(*(states +rankOfState))->humidity += HUMIDITY;
char* currentSnow = strtok(NULL, "\t");
float SNOW;
sscanf(currentSnow, "%f", &SNOW);
(*(states +rankOfState))->snow += SNOW;
char* currentCloud = strtok(NULL, "\t");
double CLOUD;
sscanf(currentCloud, "%lf",&CLOUD);
(*(states +rankOfState))->cloud += CLOUD;
char* currentLightning = strtok(NULL, "\t");
float LIGHTNING;
sscanf(currentLightning, "%f", &LIGHTNING);
(*(states +rankOfState))->lightning += LIGHTNING;
char* currentPressure = strtok(NULL,"\t");
double PRESSURE;
sscanf(currentPressure, "%lf", &PRESSURE);
(*(states +rankOfState))->pressure += PRESSURE;
char* currentTemp = strtok(NULL, "\t\n");
double TEMP;
sscanf(currentTemp, "%lf",&TEMP);
(*(states +rankOfState))->temperature += TEMP;
if (TEMP <= states[currentStates]->lo_temp_reading)
{
states[currentStates]->lo_temp_reading = TEMP;
states[currentStates]->lo_temp_timestamp = *currentTimeStamp;
}
else if (*currentTemp > states[currentStates]->hi_temp_reading)
{
states[currentStates]->hi_temp_reading = *currentTemp;
states[currentStates]->hi_temp_timestamp = *currentTimeStamp;
}
currentStates++;
}
}
}
如果我注释掉这些行,我的输出打印但是,它只分析一行。
if (TEMP <= states[currentStates]->lo_temp_reading)
{
states[currentStates]->lo_temp_reading = TEMP;
states[currentStates]->lo_temp_timestamp = *currentTimeStamp;
}
else if (*currentTemp > states[currentStates]->hi_temp_reading)
{
states[currentStates]->hi_temp_reading = *currentTemp;
states[currentStates]->hi_temp_timestamp = *currentTimeStamp;
}
这是我使用的辅助函数:
int compareOrder(struct climate_info **states, char codex[3], int currentStates) //returns the order of each state in the array
{
int order = 0;
while (order < currentStates) //while order is less than number of states analyzed
{
if(strcmp((states[order])->code, codex) == 0) //if the states is present
{
return order;
}
order++; //increment here to check every line for when to update state codes
}
return -1; //returns -1 the state is not prsent in struct
}
int countStates(struct climate_info **states) //function to count number of states present
{
int num = 0;
while(num < 50 && states[num] != NULL)
{
num++;
}
return num;
}
你的代码有很多问题,很遗憾,缺少很多信息,所以这个答案是基于假设的。
编辑: 好的,这部分在您对问题的最新编辑中已经过时了;仍然:建议的签名是优越的,因为它不依赖于硬编码的最大数组长度,您另外提供为 'magic number'...
首先,countStates
函数;我假设它看起来或多或少如下:
size_t countStates(struct climate_info** states)
{
struct climate_info** end = states;
while(*end)
++end;
return end - states;
}
现在的问题是您可以轻松地超出数组边界进行迭代,从而导致未定义的行为并可能已经在此函数中崩溃。要修复,总数组 size/length 以及:
size_t countStates(struct climate_info** states, size_t length)
{
struct climate_info** end = states;
while(length-- && *end)
++end;
return end - states;
}
然后我们进入实际的功能(不要怀疑更改formatting/syntax,如果不另外说明,它们是等价的-这些是我个人的喜好...):
// (size_t is more appropriate than int here...)
void analyze_file(FILE* file, struct climate_info* states[], size_t num_states)
{
const size_t line_sz = 100;
char line[line_sz];
size_t currentStates = countStates(states, num_states);
while (fgets(line, line_sz, file) != NULL)
{
char* foundCode = strtok(line, "\t");
int rankOfState = compareOrder(states, foundCode, currentStates);
if(rankOfState == -1)
{
// new states available at all?
if(currentStates == num_states)
{
// some appropriate error handling - need to decide you!
// for now, just returning from function:
return;
}
// just allocate one struct (assumption):
states[currentStates] = (struct climate_info *) malloc(sizeof(struct climate_info));
// always check the result of malloc!
if(!states[currentStates])
{
// allocation failed, no memory available on OS!!!
// some appropriate error handling - need to decide you!
// for now, just returning from function:
return;
}
// prefer strncpy to assure you don't copy past the end!
// sure, it will fill overdue bytes with 0, but still we are safer
// (assumption: climate_info contains an array!)
strncpy(states[currentStates]->code, foundCode, sizeof(states[currentStates]->code));
states[currentStates]->num_records = 1;
// ...
// now you created a new struct with malloc; be aware
// that memory is uninitialized and could contain *ANY*
// data, reading uninitialized memory is undefined behaviour!
//if (TEMP < states[currentStates]->lo_temp_reading || states[currentStates]->lo_temp_timestamp == 0)
//{
states[currentStates]->lo_temp_reading = TEMP;
// states[currentStates]->lo_temp_timestamp = TIMESTAMP;
//}
//if (TEMP > states[currentStates]->hi_temp_reading || states[currentStates]->hi_temp_timestamp == 0)
//{
states[currentStates]->hi_temp_reading = TEMP;
states[currentStates]->hi_temp_timestamp = TIMESTAMP;
//}
// (it's a new set anyway, so just set the values...)
currentStates++;
}
else
{
++states[rankOfState]->num_records; // just a little bit simpler...
// ...
states[rankOfState]->temperature += TEMP;
if (TEMP <= states[currentStates]->lo_temp_reading)
{
states[currentStates]->lo_temp_reading = TEMP;
states[currentStates]->lo_temp_timestamp = *currentTimeStamp;
}
// this should not have resulted in crash, but assign a bad value!
else if (TEMP /* *currentTemp */ > states[currentStates]->hi_temp_reading)
{
states[currentStates]->hi_temp_reading = TEMP /* *currentTemp */;
states[currentStates]->hi_temp_timestamp = *currentTimeStamp;
}
// same for timestamp in both branches: you don't want to assign first character of string,
// but the parsed value (e. g. 1012, if string was "1012", *... would deliver 49
// (ASCII code of character `1`; assuming you have ASCII compatible encoding)
// wrong in this branch: you did NOT add a new element
//currentStates++;
}
}
}
如前所述:这是基于我认为您正在尝试做的事情。如果我的假设是错误的,请发表评论...