【问题标题】:mktime() seg faultmktime() 段错误
【发布时间】:2012-12-02 21:58:29
【问题描述】:

我正在尝试向包含日期信息的事件结构重复添加一周。我这样做是为了在某个时间之前创建一个事件的多个实例。我的 mktime 函数出现段错误,其中 full_time = mktime(&caltime);我不知道为什么。

void multiple(icalevent event, int is_location){
    icalevent temp;
    int rrule_bound = atoi(event.rrule);
    int rtime_bound = atoi(event.rtime);
    int start_bound = atoi(event.start);
    int stime_bound = atoi(event.stime);
    char buffer[9];
    struct tm caltime;
    time_t full_time;
    char time_str[15];

    temp = cpystruct(event, is_location); 
    while((start_bound <= rrule_bound) && (stime_bound <= rtime_bound)){
        memset(&caltime, 0, sizeof(struct tm));
        strncpy(time_str, temp.start, 9);
        strncat(time_str, temp.stime, 6);

        strptime(time_str, "%Y%m%d%H%M%S", &caltime);
        caltime.tm_mday += 7;
        full_time = mktime(&caltime);
        if(caltime.tm_isdst == 1){
            caltime.tm_hour -= 1;
        }
        full_time = mktime(&caltime);

        strftime(buffer, 9, "%Y%m%d", &caltime);
        start_bound = atoi(buffer);
        strncpy(temp.end, buffer, 8);
        strncpy(temp.start, buffer, 8);

        if((start_bound <= rrule_bound) && (stime_bound <= rtime_bound)){
            /*create a sort string*/

            calendar[percent_full] = cpystruct(temp, is_location);
            printst(calendar[percent_full]);
            percent_full++;
        }
        else{
            break;
        }

    }

    return;
    }

icalevent 结构:

    typedef struct{
        char start[9]; /*"YYYYMMDD*/
        char stime[7]; /*"HHMMSS"*/
        char end[9]; /*"YYYYMMDD"*/
        char etime[7]; /*"HHMMSS"*/
        char rrule[9]; /*"YYYYMMDD"*/
        char rtime[7]; /*"HHMMSS"*/
        char *location; /*"2343 fake street"*/
        char *summary; /*"Halloween party"*/
        char *sort_str; /*"YYYYMMDDHHMMSSHalloween party*/
     } icalevent

编辑

icalevent cpystruct(icalevent temp, int is_location) {
    icalevent perm;
    strncpy(perm.start, temp.start, 9);
    strncpy(perm.stime, temp.stime, 7);
    strncpy(perm.end, temp.end, 9);
    strncpy(perm.etime, temp.etime, 7);
    strncpy(perm.rrule, temp.rrule, 9);
    strncpy(perm.rtime, temp.rtime, 7);
    if(is_location) {
        perm.location = strdup(temp.location);
    } else {
        perm.location = NULL;
    }

    perm.summary = strdup(temp.summary);
    perm.sort_str = strdup(temp.sort_str);
    return perm;
}

【问题讨论】:

  • cpystruct 是如何定义的?
  • icalevent cpystruct(icalevent temp, int is_location){ icalevent perm; strncpy(perm.start, temp.start, 9); strncpy(perm.stime, temp.stime, 7); strncpy(perm.end, temp.end, 9); strncpy(perm.etime, temp.etime, 7); strncpy(perm.rrule, temp.rrule, 9); strncpy(perm.rtime, temp.rtime, 7); if(is_location){ perm.location = strdup(temp.location); }else{ perm.location = NULL; } perm.summary = strdup(temp.summary); perm.sort_str = strdup(temp.sort_str); return perm; }
  • 我在您的问题中添加了cpystruct。那里更容易阅读。您可以自己轻松地做到这一点。只需使用问题下方的小“编辑”链接即可。
  • 您可以通过使用sizeof(temp.start) 代替9 等来提高cpystruct 代码的可靠性。您也可以使用memmove()memcpy() 代替strncpy()。但该功能存在问题并不明显。您不检查来自strptime() 的返回值;如果失败,您将得到一个严重错误初始化的变量,您将其传递给mktime()

标签: c segmentation-fault mktime


【解决方案1】:

很可能,您的问题不是mktime,而是您的副本声明之一。 第一个是

strncat(time_str, temp.stime, 6);

time_str 很可能不会被 NUL 终止。

这里也一样

strncpy(temp.end, buffer, 8);
strncpy(temp.start, buffer, 8);

temp.endtemp.start 之前可能会被 NUL 终止,但你不能确定。只需改用strcpy

下一个是

calendar[percent_full] = cpystruct(temp, is_location);
printst(calendar[percent_full]);
percent_full++;

我没有看到calendar 结尾的检查。因此,可能会有超出日历末尾的写入。

顺便说一句,当你这样做时

if(caltime.tm_isdst == 1){
    caltime.tm_hour -= 1;
}

tm_hour 可能会变成负数。

【讨论】:

  • 好的,我已经对以下 strncpys 和 strncats 进行了更改。我确保检查日历,这很好,因为一旦它完全充满内存,就会使用 realloc() 重新分配。如果 tm_hour 变为负数,我们再次调用 mktime(),它不会将小时重置为正确的格式吗?
  • strcpy(time_str, temp.start); strcat(time_str, temp.stime); strptime(time_str, "%Y%m%d%H%M%S", &caltime); caltime.tm_mday += 7; full_time = mktime(&caltime);如果(caltime.tm_isdst == 1){ caltime.tm_hour -= 1; } full_time = mktime(&caltime); strftime(buffer, 9, "%Y%m%d", &caltime); strftime(buffer, sizeof(buffer), "%Y%m%d", &caltime); strncpy(temp.start,缓冲区,8); temp.start[8] = '\0'; strncpy(temp.end, 缓冲区, 8); temp.end[8] = '\0';
  • @user1871057 你对 mktime 是正确的。根据mktime,它规范了struct tm字段。
  • 哦,好吧,对于为什么会出现段错误,您还有其他建议吗?当我运行调试器时,它会在与 mktime 函数相同的行上引发段错误错误。
  • @user1871057 除了我给出的建议之外,并非如此。根据 cpystruct 的定义方式,也可能存在问题。但这只是猜测。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-23
  • 2015-06-06
  • 1970-01-01
  • 2013-07-10
  • 2013-10-11
  • 1970-01-01
相关资源
最近更新 更多