C 程序因指针赋值而崩溃
C program crashes because of pointer assignment
我正在为 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;
}
知道为什么会这样吗?我对指针比较陌生,所以我很容易犯一个愚蠢的错误。提前致谢。
编辑谢谢你们的回答和耐心,试图掌握指点。
指针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
指向有效内存。
如果您的主函数中确实需要指针,请调用 malloc(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)
永远不要使用未初始化的指针或取消引用空指针,你所做的是未定义的行为,世界上任何事情都可能发生。
您定义了一个函数 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
.
我正在为 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;
}
知道为什么会这样吗?我对指针比较陌生,所以我很容易犯一个愚蠢的错误。提前致谢。
编辑谢谢你们的回答和耐心,试图掌握指点。
指针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
指向有效内存。
如果您的主函数中确实需要指针,请调用 malloc(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)
永远不要使用未初始化的指针或取消引用空指针,你所做的是未定义的行为,世界上任何事情都可能发生。
您定义了一个函数 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
.