2013-10-04 144 views
0

每当我执行这个程序时,都会引发分段错误。该程序很简单:计算给定字符串中元音的数量。这是程序:为什么我在此while循环中出现分段错误?

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <ctype.h> 
#include <assert.h> 

int vowelC(char *in, int c){ 
    //Declarations 
    int i; //Dummy index 
    char a; //Temp variable 

    //Validate input 
    if(!in || c == 0) return 1; 

    //Main execution 

    //Convert to all lower case 
    while(in[i] != '\0'){ 
     a=in[i]; 
     if('A' <= a && a <= 'Z') 
       a-= ('A' - 'a'); 
     in[i] = a; 
     i++; 
    } 

    //Count the number of vowels 
    while(!in[i]){ 
      if(in[i] == 'a' || in[i] == 'e' || in[i] == 'i' || in[i] == 'o' || in[i] == 'u') 
        c++; 
    } 
    return 0;      
} 

void printUsage(void){ 
    printf("\n\nThis program will count the number of vowels from an entered character string.\n\t[-c <count>] [-h help]\n\n"); 
} 

int main(int argc, char **argv){ 
    //Declarations 
    int i; //Dummy index 
    int j; //Dummy index 
    int count = 0; 
    int err; 
    int strsize = 0; 

    //Is there at least some user input? 
    if(argc == 1){ 
     printUsage(); 
     return 1; 
} 

//Determine string size if there is more than two user arguments 
for(i=2; i<argc; i++){ 
     strsize += strlen(argv[i]); 
     if (argc > i+1) 
      strsize++; 
} 

//Declare an array of appropriate length to hold the entered strings 
char *in = (char *)malloc(strsize); 

//Validate input 
for(i=1; i<=(argc-2); i++){ 

     //Determine if the user requested usage 
     if(strcmp("-h", argv[i])==0){ 
         printUsage(); 
         return 1; 
     } 

     else if(strcmp("-c", argv[i])==0){ 
         //There must be at least one argument after a call 
         if((i+1) == argc){ 
            printUsage(); 
            return 1; 
         } 
         38 
         //Run another loop to retrieve string inputs 
         for(i=2; i<argc; i++){ 
            for(j=0; j != '\0'; j++){//Determine if a sting is really a string 
              if(isalpha(argv[i][j])){ 
                    printUsage(); 
                    return 1; 
              } 
          } 
          strcat(in, argv[i]); 
          if(argc > (i+1)) 
          strcat(in, " "); 
          } 

     } 

     else{//Unknown input 
         printUsage(); 
         return -1; 
     } 

//For bracket 
} 

err = vowelC(in, count); 
assert(!err); 
printf("\n\nThe number of vowels counted is %d.\n\nPlease press enter to exit...", count); 
getchar(); 
return 0; 
//Main Bracket  
} 

GDB报告在while(in[i] != '\0')发生分段故障。然而,原因没有我。任何见解都会被赞赏。

+0

如果代码已经在('-Wall -Wextra -pedantic')上编译了所有警告,编译器会警告*'i'可能使用了未初始化*。 – alk

+0

这显然是一个学生的问题,我敢说他发现这个特殊的错误非常有教育意义。他经历了一个错误,这是真正问题的后果,他学习了关于段错误的知识,他学习了如何存储数组,关于初始化变量的重要性,关于编译时没有警告的危险...... –

回答

3
int i; //Dummy index 

尚未初始化。 i具有存储类auto,这意味着它不会被初始化为默认值,因此可以包含任何垃圾值。未初始化的自动变量的值是未定义的。

1

什么是i - 它不是零

while(in[i] != '\0'){ 
+0

你必须是开玩笑的我,不敢相信我错过了。 – Mlagma

+0

没问题。我希望我能我没有犯这种事情;-) –

0

您使用

while(in[i] != '\0') 

但是你有没有初始化的 'i'

所以初始化 '我' 0

0

在'while(in [i] !''''''的值未初始化。请确保在代码中使用它们之前初始化任何变量。它是最佳做法。由于此故障,我已看到整个功能被破坏。

3

大家都已经发现了这个问题,但没有人回答这个问题,所以我会把它放在一起给你看:segfault的发生是因为你的进程试图访问它不拥有的内存,这是因为你没有未初始化i的值。

从广义上讲,数组被处理为连续的内存。您可以将数组元素语法看作是一种函数,它在根据元素类型和索引参数的大小计算出的地址处进行类型化并返回内存内容。在你的情况下,类型是char,sizeof(char)返回1,所以in[i]存储在地址in[0]加上i

索引中的一个疯狂值导致数组元素语法引用内存超出范围,导致段错误。

相关问题