我試圖找到在C.解析例行的錯誤代碼是:指針魔術有時會導致SIGSEGV
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
static const char * month_abb_names[] =
{
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
};
static const char * wday_abb_names[] =
{
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"Sun",
};
time_t mb_mktime(char * time_str)
{
struct tm msg_time;
char * cur, * next, *tmp_cur, *tmp_next, oldval;
int counter = 0, tmp_counter = 0, i;
int cur_timezone = 0, sign = 1;
time_t retval;
msg_time.tm_isdst = 0;
cur = time_str;
next = strchr(cur, ' ');
while(next)
{
oldval = (*next);
(*next) = '\0';
switch(counter)
{
case 0 :
// day of week
for(i = 0; i < 7; i++)
{
if(strncasecmp(cur, wday_abb_names[i], 3) == 0)
{
msg_time.tm_wday = i +1;
break;
}
}
break;
case 1 :
//month name
for(i = 0; i < 12; i++)
{
if(strncasecmp(cur, month_abb_names[i], 3) == 0)
{
msg_time.tm_mon = i;
break;
}
}
break;
case 2 :
// day of month
msg_time.tm_mday = strtoul(cur, NULL, 10);
break;
case 3 :
// HH:MM:SS
tmp_cur = cur;
tmp_next = strchr(cur, ':');
tmp_counter = 0;
while(tmp_next)
{
switch(tmp_counter)
{
case 0 :
msg_time.tm_hour = strtoul(tmp_cur, NULL, 10);
break;
case 1 :
msg_time.tm_min = strtoul(tmp_cur, NULL, 10);
break;
}
tmp_cur = tmp_next + 1;
tmp_next =strchr(tmp_cur, ':');
tmp_counter++;
}
msg_time.tm_sec = strtoul(tmp_cur, NULL, 10);
break;
case 4 :
// timezone
if((*cur) == '+')
{
cur++;
}
else if ((*cur) == '-')
{
sign = -1;
cur++;
}
cur_timezone = (int)strtol(cur, NULL, 10);
cur_timezone = sign * (cur_timezone/100) * 60 * 60 + (cur_timezone % 100) * 60;
break;
}
(*next) = oldval;
cur = next + 1;
next = strchr(cur, ' ');
counter++;
}
// what's left is year
msg_time.tm_year = strtoul(cur, NULL, 10) - 1900;
#ifndef __WIN32
retval = timegm(&msg_time) - cur_timezone;
#else
retval = mktime(&msg_time) - cur_timezone; // + some adjustments....
#endif
printf("final msg_time = %ld\n", retval);
return retval;
}
void getTime(char * time_str)
{
time_t time = mb_mktime(time_str);
struct tm *ts;
char buf[80];
/* Format and print the time, "ddd yyyy-mm-dd hh:mm:ss zzz" */
ts = localtime(&time);
strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", ts);
printf("%s --> %s\n", time_str, buf);
}
int main()
{
getTime("Thu Jun 16 04:53:00 +0000 2011");
printf("done.");
return 0;
}
的main
和getTime
很新,mb_mktime
僅略微修改原始
但是,該行((*next) = '\0';
)產生了SIGSEGV。我承認我相當不確定爲什麼代碼看起來像這樣...
但是,代碼在正常的應用程序中正常工作。
有人可以解釋爲什麼此代碼在一個應用程序和SIGSEGV在另一個?
讓我們看看整個代碼。可能你會修改'next'指針。我們希望看到這一點。 – mattn
正如你寫的那樣,'next = strchr(「startstring」,'')'的結果是'NULL'。所以它不應該進入循環。 – IanNorton
您正在寫入一個常量字符串。 – Anycorn