我收到此错误:细分错误(核心已转储)

时间:2020-05-22 18:22:10

标签: c function malloc free

这是一个从用户那里获取字符串并打印该字符串具有多少元音和常量的项目。当我为更清晰的代码创建功能malloc_memory和free_memory时,问题就开始了,这样我就可以调用main内部的函数,而不必直接在main函数中分配内存和空闲内存。这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define E_A_LETTERS 26
#define MAX_LENGTH 50

int check_vowels(char *p_string);
void malloc_memory(char **p_string);
void free_memory(char *p_string);

int main(void){
    // Here your code !
    char *string;
    int vowels;
    int constants;

    malloc_memory(&string);
    printf("Enter a string: ");
    fgets(string, MAX_LENGTH, stdin);

    vowels = check_vowels(string);
    constants = strlen(string) - vowels;

    printf("\nNumber of vowels : %d", vowels);
    printf("\nNumber of constants : %d\n", constants);

    free_memory(string);

}

int check_vowels(char *p_string)
{
    int i = 0;
    int count = 0;
    while(1)
    {
        if(*(p_string + i) == 'A' || *(p_string + i) == 'E' || *(p_string + i) == 'I' || *(p_string + i) == 'O' || *(p_string + i) == 'U')
            count++;
        if(*(p_string + i) == 'a' || *(p_string + i) == 'e' || *(p_string + i) == 'i' || *(p_string + i) == 'o' || *(p_string + i) == 'u')
            count ++;
        if(*(p_string + i) == '\0')
            break;
        i++;

    }
    return count;
}

void malloc_memory(char **p_string)
{
    p_string = (char **)malloc(MAX_LENGTH * sizeof(char) + 1);
    if(p_string == NULL)
    {
        printf("Unable to allocate memory...");
        exit(0);
    }
}

void free_memory(char *p_string)
{
    free(p_string);
}

我正在得到此输出-错误:

Enter a string: This is a string
Number of vowels : 4
Number of constants : 12
Segmentation fault (core dumped)

2 个答案:

答案 0 :(得分:3)

函数malloc_memory错误。

代替这些陈述

p_string = (char **)malloc(MAX_LENGTH * sizeof(char) + 1);
if(p_string == NULL)

您至少要写

*p_string = (char *)malloc(MAX_LENGTH * sizeof(char) );
if ( *p_string == NULL )

*p_string = malloc( MAX_LENGTH );
if ( *p_string == NULL )

致电fgets

之后
fgets(string, MAX_LENGTH, stdin);

您应将可能附加的换行符'\n'删除到输入的字符串中。例如

string[ strcspn( string, "\n" ) ] = '\0';

函数check_vowels可以通过以下方式编写

#include <ctype.h>

//...

size_t check_vowels( const char *p_string )
{
    const char *vowels = "AEIOU";
    size_t count = 0;

    for ( ; *p_string; ++p_string )
    {
        if ( strchr( vowels, toupper( ( unsigned char )*p_string ) ) != NULL )
        {
            ++count;
        }
    }    

    return count;
}

答案 1 :(得分:2)

如前所述,您的分配是不正确的,因此返回指向分配的空间的指针会更简单:

功能

char* malloc_memory() {

    char* p_string = malloc(MAX_LENGTH); // a char is always 1 byte and no cast needed

    if(p_string == NULL) {
        printf("Unable to allocate memory...");
        exit(0); //or return NULL to handle it in the caller
    }
    return p_string;
}

主要

char* string = malloc_memory();

另一方面,gets()是一个危险函数,容易溢出,您应该使用一种方法,将从缓冲区读取的字符串的大小限制为容器的大小,例如:

scanf("%49[^\n]", string); 

对于50 char容器。读取直到找到\n或读取49个字符。因此49个字符加上scanf添加的空终止符。