我正在为ANSI C书中的一个练习编写一个程序,当我到达这一行时程序崩溃了:
*pmonth = i;
在函数month_day。
#include <stdio.h>
void month_day(int year, int yearday, int *pmonth, int *pday);
int main(int argc, char *argv[]){
int year = 1994;
int *month;
int yearday = 288;
int *day;
month_day(year, yearday, month, day);
printf("Month = %d, day = %d", *month, *day);
return 1;
}
static char daytab[2][14] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
void month_day(int year, int yearday, int *pmonth, int *pday){
int i, leap;
leap = (year%4 == 0 && year%100 != 0) || year%400 == 0;
char *p = &daytab[leap][1];
for(i = 1; yearday> (int) *p; i++){
yearday -= *p++;
}
*pmonth = i; /*CRASHES HERE*/
*pday = yearday;
}
为什么会发生这种情况?我对指针比较新,所以我很容易犯一个愚蠢的错误。提前谢谢。
编辑谢谢你们的答案和耐心,试着掌握指针。
答案 0 :(得分:2)
指针pmonth
未初始化。所以你不应该取消引用它。您应该为指针指定一个有效的地址。为此,您可以使用&
运算符分配变量地址,也可以调用malloc(1)
。
由于您似乎不需要主函数中的指针,因此您的代码应为:
int main(int argc, char *argv[]){
int year = 1994;
int month;
int yearday = 288;
int day;
month_day(year, yearday, &month, &day);
printf("Month = %d, day = %d", month, day);
return 1;
}
在此代码中,我们向pmonth
和pday
提供变量month
和day
的地址。这些变量存在于此上下文中,因此它们的地址有效。这样,pmonth
和pday
指向有效的内存。
如果您确实需要main函数中的指针,请调用malloc(1)
为程序分配内存并将该内存块的地址存储到指针中。
答案 1 :(得分:1)
这是因为您永远不会为pmonth
创建任何指向的内存。您需要将任何指针指向某个内存以供其编辑,如果不这样且指针未初始化或NULL
则您有未定义行为。未定义的行为意味着任何事情都可能发生,包括程序崩溃或偷车。
这样的东西就足够了:
int month; // Some actual memory.
int *pmonth = &month; // pmonth now points to something real.
但话说回来,month_day
函数的要点是提供输出参数,所以即使这样就足够了:
int month, day;
month_day( ..., &month, &day)
答案 2 :(得分:0)
永远不要使用未初始化的指针或取消引用空指针,你所做的是未定义的行为,世界上任何事情都可能发生。
您已经定义了一个函数void month_day(int year, int yearday, int *pmonth, int *pday)
,它需要两个指向int(pmonth and pday
)的指针才能传递给它。您已正确传递指向int的指针,并且编译器已成功编译您的程序,但这些指针并未指向正确的内存地址。当您访问未初始化指针指向的地址(可能无效或不属于您)时,您将获得Segmentation Fault
。
分段错误是一种特殊的错误,它是由访问“不属于你”的内存引起的。它是一种帮助机制,可以防止破坏内存并引入难以调试的内存错误。
有很多方法可以获得段错误。获取段错误的常用方法是取消引用空指针:
int *p = NULL;
*p = 1;
要解决您的问题,您的代码应该类似于下面的代码
int main(int argc, char *argv[])
{
int year = 1994;
int month;
int yearday = 288;
int day;
month_day(year, yearday, &month, &day);
printf("Month = %d, day = %d", month, day);
return 0;
}
或者
您可以调用malloc
函数动态分配内存,并将malloc
函数返回的地址分配给指针变量。 Remember, to call free function to release memory allocated dynamically when you no longer need the memory
。