2015-09-16 3 views
-3

Salut en raison de mon manque de connaissances en C (deuxième année au collège). Le compilateur a mangé mon code et a construit l'application. Mais après avoir accepté la première valeur - numOfIntegers, il cesse de fonctionner et le débogage indique que la segmentation a échoué. SIGSEGV. Comment réparer cela?Erreur de segmentation dans C? Tableaux, pointeurs, fonctions

Il y a le code:

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

/* ----------------------------------------- 
    Program: Question 1 
    Author: Maggot #9 
    Email: [email protected] 
    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; 
} 
+1

Ces avertissements montrant certainement quand la compilation devrait vous donner une bonne vue de ce que votre code est comme. En déboguant, vous devez déterminer quelle ligne (ou au moins quelle fonction), en particulier segfaults. – Downvoter

+0

@cad il ne montre rien sur quelle fonction peut avoir un problème .. –

+0

Dunno ce que le débogage signifie pour vous, mais je veux dire passer par le code par gdb, en regardant les valeurs de registre, etc. – Downvoter

Répondre

2

Je peux voir ce défaut dans getName() qui accédera à la mémoire au-delà des limites du tableau

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

Je crois que vous utilisez le mauvais test, essayez

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

en supposant que value est dans la fourchette 1 .. 10 comme le tableau textuel l'indique.

2) un défaut GetValue où vous entrez dans numOfInteger mais return value, qui est uninitialised.

3) prepare la déclaration

scanf("%d",&numOfIntegers); 

ne passera pas la valeur d'entrée à l'appelant. Vous devriez avoir soit passé un pointeur vers la variable, soit renvoyé la valeur entrée.

Mais il y a peut-être beaucoup d'autres erreurs. Construisez votre programme étape par étape, en vérifiant et en essayant de le casser au fur et à mesure (avec une entrée absurde). Faites attention aux avertissements du compilateur - le deuxième défaut que j'ai énuméré en générera un.

EDIT bien ... nous allons examiner la fonction prepare qui, après la suppression du bruit est

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

Cette entrée une valeur au paramètre de la fonction qui a été adoptée. C'est légal, puisque vous pouvez utiliser un argument de la fonction de la même manière que vous pouvez une variable locale (peut-être soumise à la qualification const).

Bien que ce ne soit pas une erreur de codage, cela n'aboutit à rien. 1) vous passez généralement un argument comme celui-ci pour être utilisé par la fonction d'une certaine manière, peut-être dans ses limites et/ou dans son invite. 2) Modifier l'argument comme ceci ne retrouvera pas le chemin de l'appelant.

Voici deux façons de gérer cela.

A) la fonction retourne la valeur d'entrée

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

... 

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

B) la fonction prend un argument pointeur

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

... 

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

Merci pour l'aide. Tu avais un peu raison de préférer C++ ou C# plus que c. Et ton sanglant sur mon attitude. Cette question était d'accepter à 2 int et de faire 5 réponses de tout probablement dans la fonction principale. Mais je veux aller mieux dans la programmation et faire mes propres exigences plus élevées aux questions. P.S. J'ai obtenu la meilleure programmation 1 résultat CA et examen la première année: D –

+0

Bon pour vous Kaspar, mais blâmer les outils que vous avez à travailler avec d'autres personnes comme ... Je suis l'inverse, j'ai exploré le C++ mais toujours semblait vouloir l'héritage à l'opposé de ce que je faisais. –

+0

Alors, que diriez-vous du pointeur dont vous avez parlé? Encore du mal à les utiliser. J'apprécierais votre aide. :) –