C++ 进程在 4.017 秒后退出,返回值 3221225477

Posted

技术标签:

【中文标题】C++ 进程在 4.017 秒后退出,返回值 3221225477【英文标题】:C++ Process exited after 4.017 seconds with return value 3221225477 【发布时间】:2020-05-25 22:51:11 【问题描述】:

我是 C++ 新手,我正在尝试编写这个简单的代码来输入和显示员工数据。 我想通过地址将用户输入传递给 inputEmployee 函数,将其保存在数组中然后显示。当我进入输入员工姓名的部分时,我收到以下消息“进程在 4.017 秒后退出,返回值 3221225477”

有人可以提出解决方案或解释我的代码有什么问题吗?

我不确定我所做的是否正确。


struct Employee 
    char    name[30];
    char    surname[30];
    int     age;
    float   salary;
;

Employee* inputEmployee(struct Employee *emp, int n, int index) 
     Employee *employeeRecords = new Employee[n];
     employeeRecords[index] = *emp;
     return employeeRecords;


int displayEmployee(struct Employee *arr) 
    int arraySize = sizeof(arr)/sizeof(*arr);
    printf("\nEmployee data:");
    for(int i=0; i < arraySize; i++) 
        printf("Name: %s", arr[i].name);
        printf("Surname: %d", arr[i].surname);
        printf("Age: %d", arr[i].age);
        printf("Salary: %f\n", arr[i].salary);
    
    return 0;


int main()

    int n = 0;
    printf("\nEnter employee number :\n");
    scanf("%d", &n);
    struct Employee *eArr;

    for(int i=0; i<n; i++) 
        struct Employee *emp = NULL;

        printf("\nEnter employee data :\n");
        printf("Name ?:"); scanf("%s", emp->name);
        printf("Surname ?:"); scanf("%s", emp->surname);
        printf("Age ?:"); scanf("%d", &emp->age);
        printf("Salary ?:"); scanf("%f", &emp->salary);
        eArr = inputEmployee(emp, n, i);
    

    displayEmployee(eArr);

    return 0;

【问题讨论】:

你先是struct Employee *emp = NULL;,然后是scanf("%s", emp-&gt;name);。您还期望发生什么? 如果你使用的是 C++,那你为什么要以 C 方式做所有事情呢? 一般来说,如果有人不理解为什么 C++ 程序无法运行,那么对程序进行随机更改,例如将各种变量设置为 NULL,不太可能产生任何结果。您需要了解崩溃的原因,然后修复它。崩溃的原因是没有正确实例化对象,并取消引用未初始化的指针。将未初始化指针的取消引用替换为 NULL 指针的取消引用并不能解决问题。 我能给出的最佳建议是“你不要通过尝试去编码,看看会发生什么”——这就是所谓的猜测。 C/C++ 中的语法和使用是准确的。一行中的每个字符都有一个目的和正确的用法。如果你发现自己很想猜测,那么那个小声音应该告诉你“不要这样做——回到书本或手册页并弄清楚......” 。没有例外。 int arraySize = sizeof(arr)/sizeof(*arr); 不会给你数组中的元素数量,而是提供sizeof(arr) / sizeof (a_pointer)——不是你想要的。您必须将元素的数量作为第二个参数传递。 sizeof arr / sizeof *arr -- 仅在该范围内有效 arr 被声明为数组 当作为参数传递时(实际上是在访问时),数组被转换为指向第一个元素的指针 - 有一些与此处无关的例外情况.. 【参考方案1】:

您应该退后一步,阅读有关 C++ 中的内存管理、数组、指针和引用的内容。当你想编写 C++ 时,这是一个很难的部分,你必须学习。您绝对应该阅读更多文章。

边做边学只是成功的一半。您需要了解在后台发生了什么。您的程序可以做“某事”,即使它看起来不错,但以后可能会严重失败。但请保持警惕,继续前进。


Employee *emp = NULL; 在你的内存中创建一个指向“无处”的指针。您至少要做的事情是Employee *emp = new Employee();。这将分配可用于数据的内存。请记住,您必须为每个分配的内存使用delete 运算符。

我试图修复您的代码。我为整个数组分配了内存。

#include <cstdio>

struct Employee

  char name[30];
  char surname[30];
  int age;
  float salary;
;

//--------------------------------------------------------------------------//
int displayEmployee(Employee *arr, int count)

  printf("\nEmployee data:");
  for (int i = 0; i < count; i++)
  
    printf("Name: %s ", arr[i].name);
    printf("Surname: %s ", arr[i].surname);
    printf("Age: %d ", arr[i].age);
    printf("Salary: %f\n", arr[i].salary);
  
  return 0;


//--------------------------------------------------------------------------//
int main()

  int n = 0;
  printf("\nEnter employee number: \n");
  scanf("%d", &n);

  Employee *eArr = new Employee[n];
  for (int i = 0; i < n; i++)
  
    Employee &emp = eArr[i];

    printf("\nEnter employee data :\n");
    printf("Name ?: ");
    scanf("%s", emp.name);
    printf("Surname ?: ");
    scanf("%s", emp.surname);
    printf("Age ?: ");
    scanf("%d", &(emp.age));
    printf("Salary ?: ");
    scanf("%f", &(emp.salary));
    // eArr = inputEmployee(emp, n, i);
  
  displayEmployee(eArr, n);

  delete[] eArr;
  return 0;

【讨论】:

这很有帮助。谢谢 注意:您必须通过检查返回验证每个用户输入,并且处理EOF匹配 失败,并且您必须在下一次输入之前清除stdin 的任何无关或错误字符——否则您会临时未定义行为 或冒险一个无限循环。 大卫是正确的。为了获得工作代码,您必须验证输入。这在 C++ 中始终很重要。在最好的情况下,您的程序会崩溃。在最坏的情况下,它会做一些奇怪且不可预测的事情。【参考方案2】:

您已经有了一个很好的答案,但您还必须涵盖几个额外的点,以便对您的输入程序有信心。首先,您必须验证每个用户输入,并且必须在下一次输入之前清空 stdin 的任何其他字符。问问你自己,如果你输入"Ninety One" 换成Age,会发生什么?清除stdin 可以通过一个简单的循环继续您的C-stye 输入或使用std::cin.ignore()(如果使用iostream)来完成。

例如,当您循环收集员工数据时,您必须强制用户为每个变量输入有效的输入,然后才能进入下一个商店,例如

    for (int i = 0; i < n; i++)    /* loop for input of n empoloyees */
        struct Employee emp;

        puts ("\nEnter employee data :");
        for (;;)   /* loop continually until valid input received */
            fputs ("\n  Name ?: ", stdout);     /* prompt (fputs for \n control) */
            int rtn = scanf("%s", emp.name);    /* save return from scanf */
            if (rtn == EOF)                    /* check for manual EOF */
                puts ("(user canceled input)");
                return 0;
               /* remove any extraneous characters from stdin */
            for (char c = getchar(); c != '\n' && c != EOF; c = getchar()) 
            if (rtn == 1)                       /* if good input break loop */
                break;
        

您必须在处理数字输入时添加额外的检查以涵盖 匹配失败 情况,例如

        for (;;)   /* ditto for Age, but note the additional validation required */
            fputs ("  Age ?: ", stdout);
            int rtn = scanf ("%d", &emp.age);
            if (rtn == EOF) 
                puts ("(user canceled input)");
                return 0;
            
            for (char c = getchar(); c != '\n' && c != EOF; c = getchar()) 
            if (rtn == 1)
                break;
            fputs ("error: invalid integer input.\n", stderr);
        

如果您要求输入的数字在特定范围内,您可以添加额外的检查,例如 if (emp.age &lt; 16 || emp.age &gt; 80) 处理无效年龄的错误。

对于输出,您不需要多次调用printf(或std::cout)——一个就可以了,例如

/* No return, you must pass number of elements as second parameter */
void displayEmployee (struct Employee *arr, int n)

    puts ("\nEmployee data:");      /* no conversion, just use puts */

    for (int i=0; i < n; i++)       /* only 1 printf needed */
        printf ("\n  Name: %s\n  Surname: %s\n  Age: %d\n  Salary: %.2f\n",
                arr[i].name, arr[i].surname, arr[i].age, arr[i].salary);

还请注意,没有理由从displayEmployee 返回值,它只是一个输出函数,没有任何返回来指示函数内操作的成功或失败。

总而言之,你可以这样做:

#include <cstdio>

#define MAXN 30

struct Employee 
    char    name[MAXN];
    char    surname[MAXN];
    int     age;
    float   salary;
;

/* No return, you must pass number of elements as second parameter */
void displayEmployee (struct Employee *arr, int n)

    puts ("\nEmployee data:");      /* no conversion, just use puts */

    for (int i=0; i < n; i++)       /* only 1 printf needed */
        printf ("\n  Name: %s\n  Surname: %s\n  Age: %d\n  Salary: %.2f\n",
                arr[i].name, arr[i].surname, arr[i].age, arr[i].salary);


int main()

    int n = 0;
    fputs ("\nEnter employee number : ", stdout);
    if (scanf ("%d", &n) != 1)                     /* validate every input */
        fputs ("error: invalid integer input.\n", stderr);
        return 1;
    
    struct Employee *eArr = new struct Employee[n]; /* allocate */

    for (int i = 0; i < n; i++)    /* loop for input of n empoloyees */
        struct Employee emp;

        puts ("\nEnter employee data :");
        for (;;)   /* loop continually until valid input received */
            fputs ("\n  Name ?: ", stdout);     /* prompt (fputs for \n control) */
            int rtn = scanf("%s", emp.name);    /* save return from scanf */
            if (rtn == EOF)                    /* check for manual EOF */
                puts ("(user canceled input)");
                return 0;
               /* remove any extraneous characters from stdin */
            for (char c = getchar(); c != '\n' && c != EOF; c = getchar()) 
            if (rtn == 1)                       /* if good input break loop */
                break;
        
        for (;;)   /* ditto for Surname */
            fputs ("  Surname ?: ", stdout);
            int rtn = scanf("%s", emp.surname);
            if (rtn == EOF) 
                puts ("(user canceled input)");
                return 0;
            
            for (char c = getchar(); c != '\n' && c != EOF; c = getchar()) 
            if (rtn == 1)
                break;
        
        for (;;)   /* ditto for Age, but note the additional validation required */
            fputs ("  Age ?: ", stdout);
            int rtn = scanf ("%d", &emp.age);
            if (rtn == EOF) 
                puts ("(user canceled input)");
                return 0;
            
            for (char c = getchar(); c != '\n' && c != EOF; c = getchar()) 
            if (rtn == 1)
                break;
            fputs ("error: invalid integer input.\n", stderr);
        
        for (;;)   /* ditto for Salary with same note */
            fputs ("  Salary ?: ", stdout);
            int rtn = scanf ("%f", &emp.salary);
            if (rtn == EOF) 
                puts ("(user canceled input)");
                return 0;
            
            for (char c = getchar(); c != '\n' && c != EOF; c = getchar()) 
            if (rtn == 1)
                break;
            fputs ("error: invalid floating-point input.\n", stderr);
        
        eArr[i] = emp;  /* simply assign struct to element */
    

    displayEmployee(eArr, n);

    return 0;

使用/输出示例

$ ./bin/empstruct

Enter employee number : 3

Enter employee data :

  Name ?: Mickey
  Surname ?: Mouse
  Age ?: 91
  Salary ?: 88.82

Enter employee data :

  Name ?: Minnie
  Surname ?: Mouse
  Age ?: 88
  Salary ?: 93.25

Enter employee data :

  Name ?: Goofy
  Surname ?: Dog
  Age ?: 85
  Salary ?: Bone and Treats
error: invalid floating-point input.
  Salary ?: .25

Employee data:

  Name: Mickey
  Surname: Mouse
  Age: 91
  Salary: 88.82

  Name: Minnie
  Surname: Mouse
  Age: 88
  Salary: 93.25

  Name: Goofy
  Surname: Dog
  Age: 85
  Salary: 0.25

尝试使用您当前的代码为AgeSalary 输入无效的输入,然后看看会发生什么(当您这样做时,请将您的手指悬停在 Ctrl+c 上...或查看哪个输入似乎被跳过)

此外,您应该选择 C ​​或 C++。您所拥有的是一个使用new 而不是malloc 进行分配的C 程序。如果你用new 替换你的分配struct Employee *eArr = malloc (n * sizeof *eArr); 那么你有一个纯C 程序。语言混用没有什么不好的,但就是不好看。

如果您还有其他问题,请告诉我。

【讨论】:

不客气。学习 C 或 C++ 更像是一段旅程,而不是仅仅做一些事情。这两种语言都有很多东西,远远超过你在一两年内消化的东西。不要让它成为一场竞赛,只是享受旅程并努力详细了解语言的各个方面,而不仅仅是粗略的水平。你学习编程就像吃鲸鱼一样——一次一个字节....

以上是关于C++ 进程在 4.017 秒后退出,返回值 3221225477的主要内容,如果未能解决你的问题,请参考以下文章

shell脚本或C程序返回值为什么不能大于255

从 python kernel32.CreateProcessA 退出代码

进程退出并返回值 3221225725 - 快速排序最坏情况,malloc 崩溃,如何解决? - C

Linux_进程终止(进程退出,进程等待(阻塞与非阻塞等待))

QProcess.start 不返回退出状态或退出代码

获取退出代码总是返回 1