[英]C segmentation fault when using strsep/strdup to manipulate a C string into struct variables
我又遇到了另一個分割錯誤( 吟 )。
為了到達我現在的位置,我在這里的其他問題上得到了幫助。
該功能的思想是:
這就是我傳遞給函數的內容:
gga_sentence結構:
typedef struct gga_sentence{
const char *untouched_sentence;
gsa_sentence *gsa;
char *sentence_id;
int time_stamp;
double latitude;
char north_south_id;
double longitude;
char east_west_id;
int quality;
int no_of_satellites;
double horizontal_dillution;
double altitude;
char altitude_units;
double geodial_seperation;
char geodial_seperation_units;
char* age_of_data_in_seconds;
char *checksum;
}gga_sentence;
gga_parsed是:
gga_sentence *ggas_parsed;
ggas_parsed = malloc(10*sizeof(gga_sentence));
其中line是一個char [100],使用從文件中讀取的行填充,這可以正常工作。
strncpy(&ggas_parsed[number_of_gga_parsed].untouched_sentence, line, strlen(line));
printf("GGA UNTOUCHED: %s", &ggas_parsed[number_of_gga_parsed].untouched_sentence);
initiative_gga_values(&ggas_parsed [number_of_gga_parsed],&ggas_parsed [number_of_gga_parsed] .untouched_sentence);
上面的printf語句:
printf("GGA UNTOUCHED: %s", &ggas_parsed[number_of_gga_parsed].untouched_sentence);
產生:
GGA UNTOUCHED: $GPGGA,151019.000,5225.9627,N,00401.1624,W,1,09,1.0,38.9,M,51.1,M,,0000*72
所以當我通過以下方式將其傳遞給上述函數時:
initiate_gga_values(&ggas_parsed[number_of_gga_parsed], &ggas_parsed[number_of_gga_parsed].untouched_sentence);
函數itef定義為:
void initiate_gga_values(gga_sentence* gga_ptr, const char* sentence){
char *temp_sentence, *second_temp_ptr;
char *token;
int token_no = 0;
temp_sentence = strdup(sentence);
second_temp_ptr = temp_sentence;
printf("TS: %s", temp_sentence);
printf("2nd: %s", second_temp_ptr);
token = strsep (&second_temp_ptr,",");
while (token != NULL) {
/*if a sentence has missing data then make that clear by settings it's value to
* <EMPTY>*/
if(strlen(token)==0){
token = "<EMPTY>";
}
switch(token_no){
case 0:
gga_ptr->sentence_id = token;
//printf("%s,",gga_ptr->sentence_id);
break;
case 1:
/*atoi converts a string to an int, well a c string anyways so a char* */
gga_ptr->time_stamp = atoi(token);
//printf("%d,",gga_ptr->time_stamp);
break;
case 2:
/*strtod coverts a string to a double, well a c string anyways so a char* */
gga_ptr->latitude = strtod(token, NULL);
//printf("%f,",gga_ptr->latitude);
break;
case 3:
gga_ptr->north_south_id = *token;
//printf("%c,",gga_ptr->north_south_id);
break;
case 4:
gga_ptr->longitude = strtod(token, NULL);
//printf("%f,",gga_ptr->longitude);
break;
case 5:
gga_ptr->east_west_id = *token;
//printf("%c,",gga_ptr->east_west_id);
break;
case 6:
gga_ptr->quality = atoi(token);
//printf("%d,",gga_ptr->quality);
break;
case 7:
gga_ptr->no_of_satellites = atoi(token);
//printf("%d,",gga_ptr->no_of_satellites);
break;
case 8:
gga_ptr->horizontal_dillution = strtod(token, NULL);
//printf("%f,",gga_ptr->horizontal_dillution);
break;
case 9:
gga_ptr->altitude = strtod(token, NULL);
//printf("%f,",gga_ptr->altitude);
break;
case 10:
gga_ptr->altitude_units = *token;
//printf("%c,",gga_ptr->altitude_units);
break;
case 11:
gga_ptr->geodial_seperation = strtod(token, NULL);
//printf("%f,",gga_ptr->geodial_seperation);
break;
case 12:
gga_ptr->geodial_seperation_units = *token;
//printf("%c,",gga_ptr->geodial_seperation_units);
break;
case 13:
/*This is never used in the sentenced given*/
gga_ptr->age_of_data_in_seconds = token;
//printf("%s,",gga_ptr->age_of_data_in_seconds);
break;
case 14:
gga_ptr->checksum = token;
//printf("%s",gga_ptr->checksum);
break;
}
token_no++;
token = strsep (&second_temp_ptr, ",");
}
printf("untouched: %s\n", sentence);
printf("Second print of TS: %s\n", temp_sentence);
printf("second print of second_temp: %s\n", second_temp_ptr);
free(temp_sentence);
exit(1); //DBUGGING PURPOSES
}
該函數的輸出為:
TS: $GPGGA,151019.000,5225.9627,N,00401.1624,W,1,09,1.0,38.9,M,51.1,M,,0000*72
2nd: $GPGGA,151019.000,5225.9627,N,00401.1624,W,1,09,1.0,38.9,M,51.1,M,,0000*72
untouched: $GPGGA,151019.00�(m
Second print of TS: $GPGGA
second print of second_temp: (null)
因此,如果我添加此printf語句:
printf("testing untouched: %s", gga_ptr->untouched_sentence);
進入initiate_gga_values函數,就在exit(1)之前我遇到了分段錯誤。 使用額外的打印行再次運行代碼的輸出將打印出gga_ptr-> untouched_sentence,從而產生:
GGA UNTOUCHED: $GPGGA,151019.000,5225.9627,N,00401.1624,W,1,09,1.0,38.9,M,51.1,M,,0000*72
TS: $GPGGA,151019.000,5225.9627,N,00401.1624,W,1,09,1.0,38.9,M,51.1,M,,0000*72
2nd: $GPGGA,151019.000,5225.9627,N,00401.1624,W,1,09,1.0,38.9,M,51.1,M,,0000*72
untouched: $GPGGA,151019.00��b
Second print of TS: $GPGGA
second print of second_temp: (null)
Segmentation fault (core dumped)
我不知道發生了什么。
有任何想法嗎?
干杯,克里斯。
這是錯誤的:
const char* untouched_sentence;
strncpy(&ggas_parsed[number_of_gga_parsed].untouched_sentence, line, strlen(line));
printf("GGA UNTOUCHED: %s", &ggas_parsed[number_of_gga_parsed].untouched_sentence);
strncpy
的第一個參數應該是將副本放入其中的緩沖區,您已為其提供了指向結構的指針。 第三個參數應該是目標緩沖區的大小,而不是輸入!
您需要做:
char* untouched_sentence;
ggas_parsed[number_of_gga_parsed].untouched_sentence = malloc(<size>);
如果擔心長行, <size>
需要用一些限制strlen(line)。
然后:
strncpy(ggas_parsed[number_of_gga_parsed].untouched_sentence, line, strlen(line));
printf("GGA UNTOUCHED: %s",ggas_parsed[number_of_gga_parsed].untouched_sentence);
我認為您需要從一個簡單的示例開始,着手進行內存管理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.