C 为什么我的程序在声明这两个变量时崩溃?
我试图用C语言制作一个解释器,它工作得很好,但是当我试图在代码中添加这两个变量时,程序就崩溃了。 幸运的是,当我在程序中添加static关键字或将变量保留为全局变量时,程序不会崩溃。 为什么会发生这种情况? 代码如下:C 为什么我的程序在声明这两个变量时崩溃?,c,variables,interpreter,C,Variables,Interpreter,我试图用C语言制作一个解释器,它工作得很好,但是当我试图在代码中添加这两个变量时,程序就崩溃了。 幸运的是,当我在程序中添加static关键字或将变量保留为全局变量时,程序不会崩溃。 为什么会发生这种情况? 代码如下: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <windows.h> //If I leave the variables here
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
//If I leave the variables here the program doesn't crash
//int esMain = 0;
//int esEnd = 0;
int main(int argc, char** argv){
FILE *f;
f = fopen(argv[1], "r+");
if(f == NULL){
perror("Error: No se encuentra el archivo\nDescripcion");
exit(1);
}
if(ferror(f)){
printf("Archivo corrupto");
exit(1);
}
printf("\nEjecutando archivo: %s\n\n\n", argv[1]);
int esMain = 0;//These two variables makes the program to crash
int esEnd = 0;
//But if I add the static keyword in both variables the program works well.
char* str;
while(1){
fgets(str, 25, f);
if(strncmp(str, "MAIN:", 5) == 0){
esMain = 1;
}
if(strncmp(str, "END.", 4) == 0){
esEnd = 1;
}
if(feof(f) != 0){
if(esMain == 0){
printf("No existe el parametro main, cierre por no tener el parametro main (poner MAIN: ENCIMA)");
exit(1);
}
if(esEnd == 0){
printf("No existe el parametro end, cierre por no tener el parametro main (poner END. ENCIMA)");
exit(1);
}
break;
}
}
rewind(f);
while(1){
fgets(str, 500, f);
if(strncmp(str, "print ", 6) == 0){
printf(str + 6);
}
if(strncmp(str, "msg", 3) == 0){
if(strstr(str + 4, "check")){
MessageBox(HWND_DESKTOP, str + 10, "Check", MB_ICONINFORMATION);
}
if(strstr(str + 4, "error")){
MessageBox(HWND_DESKTOP, str + 10, "Error", MB_ICONERROR);
}
}
if(strncmp(str, "pause", 5) == 0){
getch();
}
if(feof(f) != 0){
break;
}
}
printf("\n\n\nEND EXECUTION");
fclose(f);
return 0;
}
#包括
#包括
#包括
#包括
//如果我把变量留在这里,程序就不会崩溃
//int-esMain=0;
//int-esEnd=0;
int main(int argc,字符**argv){
文件*f;
f=fopen(argv[1],“r+”);
如果(f==NULL){
perror(“错误:无文档描述”);
出口(1);
}
if(费罗(f)){
printf(“Archivo corrupto”);
出口(1);
}
printf(“\nEjecutando archivo:%s\n\n\n”,argv[1]);
int esMain=0;//这两个变量使程序崩溃
int-esEnd=0;
//但是,如果我在两个变量中都添加static关键字,程序就会运行良好。
char*str;
而(1){
fgets(str,25,f);
如果(strncmp(str,“MAIN:”,5)=0){
esMain=1;
}
如果(strncmp(str,“END.”,4)==0){
esEnd=1;
}
如果(feof(f)!=0){
如果(esMain==0){
printf(“不存在主要参数,不存在主要参数(主要参数:ENCIMA)”;
出口(1);
}
如果(esEnd==0){
printf(“不存在el参数端,不存在tener el参数主管道(poner end.ENCIMA)”;
出口(1);
}
打破
}
}
倒带(f);
而(1){
fgets(str,500,f);
如果(strncmp(str,“print”,6)=0){
printf(str+6);
}
如果(strncmp(str,“msg”,3)=0){
如果(strstr(str+4,“检查”)){
消息框(HWND_桌面,str+10,“检查”,MB_图标信息);
}
if(strstrstr(str+4,“错误”)){
MessageBox(HWND_桌面,str+10,“错误”,MB_ICONERROR);
}
}
如果(strncmp(str,“暂停”,5)=0){
getch();
}
如果(feof(f)!=0){
打破
}
}
printf(“\n\n\n执行”);
fclose(f);
返回0;
}
字符*str代码>声明可能是破坏代码的原因。当您将其声明为全局时,它存储在内存中与在函数中声明时不同的位置
您很幸运,您的程序将其作为全局变量使用。因为您没有在内存中保留任何位置,所以变量正在访问一些它不应该访问的内存(未定义的行为)Lucky可能不是最好的形容词,因为由于其未定义的行为,您可能认为您的程序工作正常,而事实并非如此(如果程序崩溃,您将100%认为存在错误)
要解决此问题,您可以执行以下操作之一:
动态分配它:char*str=(char*)malloc(sizeof(char)*25)代码>
将其更改为br一个数组:charstr[25]代码>
指向现有数组:char arr[25];char*str=arr代码>
char*str代码>声明可能是破坏代码的原因。当您将其声明为全局时,它存储在内存中与在函数中声明时不同的位置
您很幸运,您的程序将其作为全局变量使用。因为您没有在内存中保留任何位置,所以变量正在访问一些它不应该访问的内存(未定义的行为)Lucky可能不是最好的形容词,因为由于其未定义的行为,您可能认为您的程序工作正常,而事实并非如此(如果程序崩溃,您将100%认为存在错误)
要解决此问题,您可以执行以下操作之一:
动态分配它:char*str=(char*)malloc(sizeof(char)*25)代码>
将其更改为br一个数组:charstr[25]代码>
指向现有数组:char arr[25];char*str=arr代码>
char*str代码>这是一个未初始化的指针,它不特别指向任何地方,但是fgets(str,25,f)代码>尝试对其进行写入,即。在使用前使str
指向有效的字符串缓冲区,例如char-str[25]代码>或char*str=malloc(25)代码>。如果您通过malloc
选择动态内存分配路径,请记住在程序结束时也要free(str)
,您可能还希望将malloc的返回值强制转换为char*
,因为按照标准,它返回void*
打开编译器警告以帮助捕获这些简单错误。if(feof)(f)!=0){
太晚了。使用while(fgets(str,500,f)){
printf(str+6);
是黑客利用的沃土,因为printf()
首先需要一个格式字符串。使用printf(“%s”,str+6)
char*str;
这是一个未初始化的指针,它不特别指向任何地方,但是fgets(str,25,f);
尝试写入它,也就是说。在使用它之前,让str
指向一个有效的字符串缓冲区,例如char-str[25];
或char*str=malloc(25)如果你选择动态内存分配的路径是通过malloc
,记住在程序结束时也要free(str)
,你可能还想将malloc的返回值强制转换为char*
,因为按照标准,它返回void*
,打开编译器警告以帮助捕获这些简单错误。if(feof)(f)(= 0){<代码> >(fGET(STR,500,f)){< /代码>代码> PrtTf(STR + 6);< /C> >是黑客开发的沃土,如<代码> Prtff()>代码>首先期望一个格式字符串。使用<代码> PrtTf(“%s”,STR + 6);< /代码> CAST不需要。考虑<代码> STR=Malc(SsieOF*STR* 25)
以避免错误匹配类型。谢谢,它成功了。老实说,我的编译器没有给出任何错误。我