使用Malloc输入String后程序崩溃

时间:2017-12-27 16:55:59

标签: c string pointers

程序在输入长字符串后崩溃了。我认为该程序无法处理用户输入的大量字符串。你能帮我解决一下我的代码错误吗?

一个简单的C程序,使用指针计算字符串中的元音和辅音。

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

int main()
{
    char * sEnteredString= NULL;
    int i;
    int sizeString;
    int vowel=0;
    int consonants=0;

    printf("A program that counts the number of vowels and consonants in a string\n");
    printf("Enter a string:\t");
    sEnteredString = (char*)malloc(sizeof(sEnteredString));
    scanf(" %s",sEnteredString);

    if (sEnteredString==NULL)
    {
        printf("OUT OF MEMORY\n");
    }
    else
    {
        sizeString=strlen(sEnteredString);

        for (i=0; i<sizeString;i++)
        {
            if((sEnteredString[i] == 'A') || \
               (sEnteredString[i] == 'a') || \
               (sEnteredString[i] == 'E') || \
               (sEnteredString[i] == 'e') || \
               (sEnteredString[i] == 'I') || \
               (sEnteredString[i] == 'i') || \
               (sEnteredString[i] == 'O') || \
               (sEnteredString[i] == 'o') || \
               (sEnteredString[i] == 'U') || \
               (sEnteredString[i] == 'u'))
            {
                vowel ++;
            }
            else
            {
                consonants ++;
            }
        }
            printf("Entered vowel: %d \nEntered constants: %d\n", vowel, consonants);
    }

    free(sEnteredString);
    return 0;
}

2 个答案:

答案 0 :(得分:1)

为什么(错误地)为此分配动态内存:

sEnteredString = (char*)malloc(sizeof(sEnteredString));

其中sizeof(sEnteredString)是char指针的大小(通常是4或8)?进入像#34的字符串时太短了嘿!华夫饼&#34;!

当你能做到:

char sEnteredString[100];

然后

scanf("%99s",sEnteredString);

所以你自动分配你的字符串,以防有人输入过大的字符串。

重要提示:最后不要free(sEnteredString)

除此之外:使用toupperswitch/case语句来避免所有这些ifs。并记住计算辅音,而不是不是元音的字符(如空格,标点符号......)

答案 1 :(得分:1)

主要问题是你根据指针的大小为8个字符或4个字符分配内存。 (因32-64位系统而异)。使用NUL终止字符时,您的字符串不太可能包含4或8个字符。然后你尝试读取比这更大的字符串,你有非法的内存访问...访问你没有分配的东西。你显然有未定义的行为。(在你的案例程序中崩溃)。

第二个问题是您在使用之前检查malloc是不是应该?是的..但你没有遵循这一点。

sEnteredString = malloc(50);
if( sEnteredString == NULL){

 /* error */
}
else{
   if( scanf("49%s",sEnteredString)!= 1){
     // error
   }
   // at this point you are happy that sEnteredString points to
   // a nul terminated char array 
   // strlen can be used safely here.
   size_t sizestring  = strlen(sEnteredString);

}
...
free(sEnteredString);

是的,另一件事是你不应该转换malloc的返回值 - 这是多余的。

另请注意,我使用size_t来保存strlen的返回值。

是的,轻松地检查你做了什么

   if( strchr("aAeEiIoOuU",sEnteredString[i]) != NULL ){
     // you got a vowel
   }

还要记住一件事strlen应该得到一个指向空终止字符数组的指针。如果您没有提供,那么您将有未定义的行为。

代码

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

int main(void)
{
    char * s;

    s = malloc(50);  
    if (s == NULL)
    {
        perror("Malloc failed\n");
        exit(EXIT_FAILURE);
    }
    else
    {
        printf("A program that counts the number of vowels and consonants in a string\n");
        printf("Enter a string:\t");

        if(scanf("%49s",s)!= 1){
            fprintf(stderr, "%s\n", "Error in input");
            free(s);
            exit(EXIT_FAILURE);
        }
        size_t sz = strlen(s);
        size_t vowel = 0,consonants = 0;
        for (size_t i=0; i<sz; i++)
        {
            strchr("aAeEiIoOuU",s[i]) ? vowel++ : consonants++;
        }
        printf("Entered vowel: %zu \nEntered constants: %zu\n", vowel, consonants);
    }
    free(s);
    return EXIT_SUCCESS;
}