【问题标题】:I am getting this Error: Segmentation fault (core dumped)我收到此错误:分段错误(核心转储)
【发布时间】:2020-09-09 16:15:24
【问题描述】:

这是一个从用户那里获取字符串并打印字符串有多少元音和常量的项目。当我为更清晰的代码创建 fanctions 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)

【问题讨论】:

  • 当你写“常量的数量”时,你的意思可能是“辅音的数量吗?
  • *(p_string + i) 的构造非常常见,有一个更易读的快捷方式:p_string[i]。
  • 不,所以目的不是(总是)为您提供现成的解决方案。其目的是帮助您提出解决方案。
  • 另外,辅音的数量不正确。仅仅因为一个字符不是元音并不能使它成为辅音。

标签: c function malloc free


【解决方案1】:

函数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;
}

【讨论】:

  • 还有*p_string = malloc(...) 而不是*p_string = (char *)malloc(...)。
  • 成功了。但我不明白为什么它应该是 char * 而不是 char **
  • @andreasm4 您通过引用传递了指针字符串,即通过指向它的指针。在函数中,您必须更改引用的指针而不是指向指针字符串的指针。
  • @andreasm4 您将 &amp;string 作为指向指针的有效指针传递。所以p_string(一个char **)已经定义为string的地址,不需要分配。 *p_string 是您需要分配的char *。因为p_string 是char **,那么*p_string 是char *。
  • @lurker 我现在完全明白你告诉我的了。非常感谢
【解决方案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 添加的空终止符。

【讨论】:

    猜你喜欢
    • 2014-08-04
    • 2012-11-19
    • 1970-01-01
    • 2016-05-20
    • 1970-01-01
    • 2016-12-28
    • 2015-06-25
    • 2021-06-03
    相关资源
    最近更新 更多