1

每当我执行此程序时,都会引发分段错误。该程序很简单:计算给定字符串中元音的数量。这是程序:

#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'). 然而,原因让我无法理解。任何见解都值得赞赏。

4

5 回答 5

4

每个人都发现了问题,但没有人回答这个问题,所以我将它放在一起:出现段错误是因为你的进程试图访问它不拥有的内存,这是因为你没有初始化的值i

从广义上讲,数组作为连续内存来处理。您可以将数组元素语法视为一种函数,它类型转换并返回根据元素类型的大小和索引参数计算得出的地址处的内存内容。在您的情况下,类型是 char,并且 sizeof(char) 返回 1,因此in[i]存储在in[0]plus的地址i

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

于 2013-10-04T06:29:34.057 回答
3
int i; //Dummy index

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

于 2013-10-04T06:14:45.200 回答
1

什么是i- 它不是零

while(in[i] != '\0'){
于 2013-10-04T06:15:27.397 回答
0

您正在使用

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

但你还没有初始化 'i'

所以用 0 初始化 'i'

于 2013-10-04T06:17:31.703 回答
0

在 'while(in[i] != '\0')' 行中 - 'i' 的值未初始化。请确保在代码中使用它们之前初始化任何变量。这是最佳实践。我有看到由于此故障而导致整个功能损坏。

于 2013-10-04T06:21:01.017 回答