简体   繁体   English

C中的分段错误? 数组、指针、函数

[英]Segmentation fault in C? Arrays, pointers, functions

Hi due to my lack of knowledge in C (second year in college).嗨,由于我缺乏 C 知识(大学二年级)。 Compiler ate my code and built the app.编译器吃了我的代码并构建了应用程序。 But after accepting first value - numOfIntegers it stops working and debugging tells that the segmentation has been failed.但是在接受第一个值后 - numOfIntegers 它停止工作并且调试告诉分段失败。 SIGSEGV. SIGSEGV。 How to fix that?如何解决?

There is the code:有代码:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

/* -----------------------------------------
    Program: Question 1
    Author: Maggot #9
    Email: maggot99999@gmail.com
    ID: B00076450
    Date: 16 September 2015
    Purpose: Who knows?
   ------------------------------------------ */

void wait(int);
void controlMenu(int, int[]);
int sumOfIntegers(int, int[]);
int avgOfIntegers(int, int[]);
int prodOfIntegers(int, int[]);
int minInteger(int, int[]);
int maxInteger(int, int[]);


const char * getName (int value)
{

  static char * arrayName[] = {"first","second","third", "fourth",
    "fifth","sixth", "seventh", "eighth", "ninth", "tenth"};

  static char badValue[] = "unknown";

  if (value<10 && value>=0)
    return arrayName[value];
  else
    return badValue;
}

int getValue(int numOfInteger)
{
  int value;
  wait(100);
  printf("Please enter %s the value:", getName(numOfInteger));
  scanf("%d",&value);

  return value;
}


void prepare(int * numOfIntegers)
{
  wait(300);
  printf("Hey again that C stupid lang\n\n");
  wait(200);
  printf("Please enter how many values you want to put: ");
  scanf("%d",numOfIntegers);
  return;
}


void initialize(int numOfIntegers,int* arrayNum[])
{
  int i;
  for(i=0; i<(numOfIntegers); i++)
    arrayNum[i] = getValue(i);

  wait(500);
  printf("\nPlease enter press any button to continue");
  wait(100);
  getch();
  wait(600);
  system("cls");
  wait(200);
  return;
}


int main()
{
  int numOfIntegers;
  prepare(&numOfIntegers);
  int arrayNum[numOfIntegers];
  initialize(numOfIntegers, &arrayNum[numOfIntegers]);
  controlMenu(numOfIntegers, &arrayNum[numOfIntegers]);
  return 0;
}


void controlMenu(int numOfIntegers, int arrayNum[])
{
  int i;
  char chooseNum;
  printf("Please choose any of the following:\n\n1. The integers accepted\n2. The sum of the integers\n3. The average of the integers\n4. The product of the integers\n5. The smallest integer\n6. The largest integer\n0. Exit menu\n");
  while(1)
  {
    chooseNum = getch();
    switch(chooseNum)
    {
      case '0':
        return;
      case '1':
        printf("\n>>> The integers are:");
        for(i=0; i<(numOfIntegers); i++)
          {
            printf("\n>>> The %s is %d", getName((i+1)), arrayNum[i]);
          }
        break;

      case '2':
        printf("\n>>> The sum of integers is: %d", sumOfIntegers(numOfIntegers, &arrayNum[numOfIntegers]));
        break;

      case '3':
        printf("\n>>> The average of integers is: %d", avgOfIntegers(numOfIntegers, &arrayNum[numOfIntegers]));
        break;

      case '4':
        printf("\n>>> The product of integers is: %d", prodOfIntegers(numOfIntegers, &arrayNum[numOfIntegers]));
        break;

      case '5':
        printf("\n>>> The smallest integer is: %d", minInteger(numOfIntegers, &arrayNum[numOfIntegers]));
        break;

      case '6':
        printf("\n>>> The largest integer is: %d", maxInteger(numOfIntegers, &arrayNum[numOfIntegers]));
        break;

      default:
        break;
    }
    printf("\n\n");
  }
}


int sumOfIntegers(int numOfIntegers,int arrayNum[])
{
  int sum=0;

  for(int i=0; i<(numOfIntegers); i++)
    sum += arrayNum[i];

  return sum;
}


int avgOfIntegers(int numOfIntegers, int arrayNum[])
{
  int average=0;

  average = sumOfIntegers(numOfIntegers, arrayNum[numOfIntegers])/numOfIntegers;

  return average;
}


int prodOfIntegers(int numOfIntegers, int arrayNum[])
{
  int i,product=0;

  for(i=0; i<(numOfIntegers); i++)
    product *= arrayNum[i];

  return product;
}


int minInteger(int numOfIntegers, int arrayNum[])
{
  int i,smallest=0;
  smallest = arrayNum[0];

  for(i=1; i<(numOfIntegers); i++)
    {
      if(smallest>arrayNum[i])
        smallest=arrayNum[i];
      else
        continue;
    }

  return smallest;
}


int maxInteger(int numOfIntegers, int arrayNum[])
{
  int i,largest=0;
  largest = arrayNum[0];

  for(i=1; i<(numOfIntegers); i++)
    {
      if(largest<arrayNum[i])
        largest=arrayNum[i];
      else
        continue;
    }

  return largest;
}


void wait(int ms)
{
  Sleep(ms);
  return;
}

I can see this fault in getName() which will access memory beyond the array bounds我可以在getName()看到这个错误,它将访问超出数组边界的内存

if (value>10 || value<1)
    return arrayName[value];

I believe you are using the wrong test, try我相信你使用了错误的测试,试试

if (value <= 10 && value > 0)
    return arrayName[value-1];

assuming value is in the range 1 .. 10 as the textual array implies.假设value在文本数组所暗示的1 .. 10范围内。

2) a fault in GetValue where you input into numOfInteger but return value , which is uninitialised. 2) GetValue中的错误,您输入numOfIntegerreturn value ,这是未初始化的。

3) in prepare the statement 3) prepare报表

scanf("%d",&numOfIntegers);

will not pass the input value back to the caller.不会将输入值传回给调用者。 You should have either passed a pointer to the variable, or returned the value input.您应该传递一个指向变量的指针,或者返回值输入。

But there might be a lot else wrong.但可能还有很多错误。 Build your program step by step, checking and trying to break it as you go (with absurd input).逐步构建您的程序,检查并尝试在运行时打破它(使用荒谬的输入)。 Pay attention to compiler warnings - the second fault I listed will generate one.注意编译器警告——我列出的第二个错误会产生一个。

EDIT okay... let's examine function prepare which after removing noise is编辑好的...让我们检查去除噪音后的功能prepare

void prepare(int numOfIntegers)
{
    scanf("%d",&numOfIntegers);
    return;
}

This inputs a value to the function parameter that was passed.这将向传递的函数参数输入一个值。 This is legal, since you can use a function argument in the same way you can a local variable (perhaps subject to const qualification).这是合法的,因为您可以像使用局部变量一样使用函数参数(可能受const限定)。

Although it's not a coding error, it does not achieve anything.虽然这不是编码错误,但它并没有实现任何目标。 1) you usually pass an argument like this to be used by the function in some way, perhaps in its limits and/or in its prompt. 1) 您通常传递这样的参数以供函数以某种方式使用,可能是在其限制和/或提示中。 2) Altering the argument like this will not find its way back to the caller. 2) 像这样改变参数不会找到返回给调用者的方法。

Here are two ways to deal with this.这里有两种方法来处理这个问题。

A) the function returns the input value A) 函数返回输入值

int prepare(void)
{
    int value;
    scanf("%d", &value);    // the address of value
    return value;
}

...

int input = prepare();
printf("%d\n", input);

B) the function takes a pointer argument B) 函数接受一个指针参数

void prepare(int *value)
{
    scanf("%d", value);     // value is already a pointer
}

...

int input;
prepare(&input);
printf("%d\n", input);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM