我正在编写一个程序,以便将一年中的某一天调整为相应的日期和月份。例如,1988年的第60天对应于第2个月(2月(的29日。
该函数使用int指针来分配生成的月份和日期:
void month_day(int year, int yearday, int *pmonth, int *pday);
我遇到了一个奇怪的错误,得到了一个分段错误。经过调试,我发现问题出在*pday
上。尽管定义了它,但C在某种程度上无法获取有效的地址(它分配地址0x0
(,所以我在尝试分配指针的地址时遇到了分段错误:
int main() {
int *pmonth, *pday;
month_day(1988, 60, pmonth, pday);
}
void month_day(int year, int yearday, int *pmonth, int *pday) {
/* some calculations on yearday */
/* Error takes place here because `pday` isn't a valid adress */
*pday = yearday;
}
我已经能够通过定义int
而不是指针并将其地址传递给函数而不是指针来克服这个问题,如:
int *pmonth, pday;
month_day(1988, 60, pmonth, &pday);
不知怎的,问题只出现在第二个指针上,正如我所说,这是因为指针*pday
在定义后被分配了一个无效的地址。
然而,我真的无法解释为什么会出现错误。
有人能解释一下为什么会发生这种事吗?
如果有必要,完整的代码在这里:
#include <stdio.h>
void month_day(int year, int yearday, int *pmonth, int *pday);
int main() {
int *pmonth, *pday;
month_day(1988, 60, pmonth, pday);
printf("%d %dn", *pmonth, *pday);
}
static char arrnonleap[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static char arrleap[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static char *daytab[] = {arrnonleap, arrleap};
/* month_day: set month, day from day of year */
void month_day(int year, int yearday, int *pmonth, int *pday) {
int i, leap;
if (year < 0 || yearday < 0 || yearday > 366)
printf("Invalid year and/or yeardayn");
leap = year%4 == 0 && year%100 != 0 || year%400 == 0;
for (i = 1; yearday > (*(daytab + leap))[i]; i++)
yearday -= (*(daytab + leap))[i];
*pmonth = i;
*pday = yearday;
}
int main(void) {
int *pmonth, *pday;
month_day(1988, 60, pmonth, pday);
printf("%d %dn", *pmonth, *pday);
}
您需要使用足够大的有效内存位置来初始化指针,以容纳int
int main(void) {
int month,day;
int *pmonth = &month, *pday = &day;
month_day(1988, 60, pmonth, pday);
printf("%d %dn", *pmonth, *pday);
}
或者只是简单的
int main(void) {
int month, day;
month_day(1988, 60, &month, &day);
printf("%d %dn", month, day);
}
int main(void) {
int *pmonth = malloc(sizeof(*pmonth)), *pday = = malloc(sizeof(*pday));
month_day(1988, 60, pmonth, pday);
printf("%d %dn", *pmonth, *pday);
free(pmonth);
free(pday);
}