【问题标题】:C segmentation fault when assigning values to the char members of my struct将值分配给我的结构的 char 成员时出现 C 分段错误
【发布时间】:2014-03-10 23:20:35
【问题描述】:

我有以下代码:

char *temp_sentence, *second_temp_ptr;
    char *token;
    int token_no = 0;

    temp_sentence = strdup(sentence);
    second_temp_ptr = temp_sentence;

    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("%s,",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("%s,",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("%s,",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("%f,",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, ",");

    }

    exit(1);
    free(temp_sentence);

}

以及下面的gga_sentence结构:

typedef struct gga_sentence{

    char *untouched_sentence;
    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;

上面的代码按预期工作,直到我尝试打印出代表我的结构的 char 成员的值,所以在 case-switch 情况下,3、5、10、12 会产生分段错误,如果我删除这些,其余结构成员按预期打印。

函数输入:

$GPGGA,151019.000,5225.9627,N,00401.1624,W,1,09,1.0,38.9,M,51.1,M,,0000*72

代码输出(不包括案例3、5、10、12的打印语句):

$GPGGA,151019,5225.962700,401.162400,1,9,1.000000,38.900000,51.100000,51.100000,0000*72

预期的输出应该与输入相同,但是这些 char 成员会导致分段错误。

标记打印时:

token: $GPGGA
token: 151019.000
token: 5225.9627
token: N
token: 00401.1624
token: W
token: 1
token: 09
token: 1.0
token: 38.9
token: M
token: 51.1
token: M
token: <EMPTY>
token: 0000*72

gdb 的输出,其中,回溯:

(gdb) where
#0  0x00007ffff7a5ef90 in _IO_vfprintf_internal (s=<optimised out>, format=<optimised out>, 
    ap=ap@entry=0x7fffffffd8b8) at vfprintf.c:1655
#1  0x00007ffff7a65ff9 in __printf (format=<optimised out>) at printf.c:34
#2  0x0000000000400daf in initiate_gga_values (gga_ptr=0x603250, 
    sentence=0x603250 "$GPGGA,151019.000,5225.9627,N,00401.1624,W,1,09,1.0,38.9,M,51.1,M,,0000*72\r\n") at stream_1_parser.c:103
#3  0x0000000000400bee in read_stream_1 (stream=0x603010) at stream_1_parser.c:40
#4  0x0000000000400a42 in main (argc=1, argv=0x7fffffffdf78) at driver.c:28

stream_1_parser.c:40 是对给定函数的调用,driver.c:28 是对 stream_1_parser.c:40 的调用

有人有什么想法吗?

干杯, 克里斯。

【问题讨论】:

  • 不相关,但第一个 strcpy() 毫无价值。你有点用strdup() 覆盖了那个基础。只是注意到。
  • @WhozCraig ye 本来应该被删除的,那是旧的尝试。对不起。
  • 别担心,你注意到了,这很重要。继续... =P

标签: c segmentation-fault


【解决方案1】:

在出现问题的情况下尝试“%c”而不是“%s”:

printf("%c,"...

当您分配给结构时,请执行以下操作:

case 5:
  gga_ptr->east_west_id = *token;

将问题案例的“token”更改为“*token”。

【讨论】:

  • 似乎有效,但不是打印字符而是打印不正确的数据,尽管令牌本身似乎是正确的,但我想这与令牌指针的类型有关。
  • 抱歉,我没有注意到您将指向字符串的指针分配给字符变量。当你打印出结构时,那肯定会给你错误的答案。我将其添加到我的答案中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-01
  • 1970-01-01
  • 2021-11-08
  • 2021-02-19
  • 2021-06-24
  • 2021-03-21
相关资源
最近更新 更多