C无法声明有效的int指针

问题描述

我正在开发一个程序,以将一年中的某天设置为等效的日期和月份。例如,1988年的60天对应于第二个月的2月29日。

函数使用int指针分配结果月份和日期:

void month_day(int year,int yearday,int *pmonth,int *pday);

我遇到一个奇怪的错误,遇到了分段错误错误。调试后,我发现问题出在*pday上。尽管定义了C,但C仍无法以某种方式获取有效的地址(它分配了地址0x0),因此在尝试分配给指针的地址时遇到了分段错误

int main() {
int *pmonth,*pday;
month_day(1988,60,pmonth,pday);
}

void month_day(int year,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,&pday);

不知何故,问题仅在于第二个指针,正如我所说,之所以会发生,是因为指针*pday在定义之后分配了无效的地址。

但是,我真的无法解释为什么错误首先发生。

有人可以解释一下为什么会这样吗?

如果有必要,完整的代码在这里

#include <stdio.h>


void month_day(int year,int *pday);

int main() {
  int *pmonth,*pday;
  month_day(1988,pday);
  printf("%d %d\n",*pmonth,*pday);
}

static char arrnonleap[] = {0,31,28,30,31};
static char arrleap[] = {0,29,31};
static char *daytab[] = {arrnonleap,arrleap};

/* month_day: set month,day from day of year */
void month_day(int year,int *pday) {
  int i,leap;

  if (year < 0 || yearday < 0 || yearday > 366)
    printf("Invalid year and/or yearday\n");
  
  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 %d\n",*pmonth,*pday);
}

您需要使用足以容纳int

的有效内存位置来初始化指针
int main(void) {
  int month,day;
  int *pmonth = &month,*pday = &day;
  month_day(1988,*pday);
}

或者简单

int main(void) {
  int month,day;
  month_day(1988,&month,&day);
  printf("%d %d\n",month,day);
}
int main(void) {
  int *pmonth = malloc(sizeof(*pmonth)),*pday = = malloc(sizeof(*pday));
  month_day(1988,*pday);
  free(pmonth);
  free(pday);
}