【发布时间】:2023-03-12 22:22:01
【问题描述】:
我在这段代码中有一个段错误错误,但我不明白为什么。有人可以解释我做错了什么。 我已经评论了我需要在这个函数中做的事情的列表。我以为我做对了,但是当我打印出来时,事实证明实际上正在发生完全不同的事情。
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;
}
【问题讨论】:
-
如果你发MCVE的话会更容易回答。
-
为什么要在 else 分支中增加 currentStates?您确实创建了任何新数据,这看起来不正确。
-
malloc(sizeof(struct climate_info) * num_states);: 如果num_states不是states数组的长度,那么你如何检测后者的结束呢?或者你想创建一个n*n数组?如果您的最终目标只是拥有一个指向单个结构的指针数组,那么您malloc-ing 内存过多,malloc(sizeof(struct climate_info))就足够了。请注意,这不会导致失败,您只是在浪费内存。 -
只是风格问题:避免全部大写的变量名,这些通常(按照惯例)用于常量(
#define SOME_THING 1012),有时也用于枚举成员(但这些是常量,也是……)。 -
const int line_sz = 100; char line[line_sz];使用 C99 功能 VLA。仅供参考 -const int不是常量,不像宏。
标签: c malloc token dynamic-memory-allocation