【问题标题】:Why my program crashes when I declare this two variables?当我声明这两个变量时,为什么我的程序会崩溃?
【发布时间】:2020-12-24 19:41:39
【问题描述】:

我正在尝试使用 C 编程语言制作一个解释器,它运行良好,但是当我尝试在代码中添加这两个变量时,程序就崩溃了。 幸运的是,当我添加 static 关键字或将变量保留为程序中的全局变量时,程序不会崩溃。 为什么会这样? 代码如下:

#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;
}

【问题讨论】:

  • char* str; 这是一个未初始化的指针,它没有特别指向任何地方,但fgets(str, 25, f); 尝试写入它,即undefined behavior。在使用之前让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() 首先需要一个 format 字符串。使用printf("%s", str + 6);

标签: c variables interpreter


【解决方案1】:

char* str; 声明可能会破坏您的代码。当你将它声明为全局时,它存储在内存中的不同位置,而不是在函数中声明它。

幸运让你的程序将它作为全局变量使用。由于您没有在内存中保留任何位置,因此该变量正在访问一些它不应该访问的内存(未定义的行为)。 幸运 可能不是最好的形容词,因为由于他未定义的行为,您可能认为您的程序正常工作,但事实并非如此(如果它崩溃了,您将 100% 有错误)。

您可以采取以下措施之一来解决此问题:

  1. 动态分配:char *str = (char*)malloc(sizeof(char)*25);

  2. 将其更改为 br 数组:char str[25];

  3. 指向现有数组:char arr[25]; char *str = arr;

【讨论】:

  • 不需要投射。考虑str = malloc(sizeof *str * 25) 以避免类型不匹配。
  • 老实说,我的编译器没有给出任何错误。我正在使用 GCC (MinGW)。
猜你喜欢
  • 1970-01-01
  • 2022-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-01
相关资源
最近更新 更多