繁体   English   中英

反转字符串时出现“分段错误核心转储错误”

[英]Getting “Segmentation fault Core Dumped Error ” while reversing a string

我正在尝试学习C,在反转字符串时遇到此错误。 我不太熟悉内存分配的东西,请您指出我做错的地方。

#include<stdio.h>
#include<string.h>
char* strrev(char *str);
int main()
{
  char str[1000];
  char *str1;
  printf("Please enter a String\n");
  gets(str);

  str1=strrev(str);
  puts(str1);

}

char* strrev(char *str)
{
  char *str1;
  int i,length,c;
  length=strlen(str);

  for (i=length-1;i<=0;i--)
  {
     *(str1+c) = *(str+i);
     c++;
  }
  *(str1+c) ='\0';
  return str1;

}

在您的strrev()函数中,未为str1分配内存。 因此, *(str1+c) = *(str+i); UB

然后, c是一个自动局部变量,在使用前未初始化。 也UB。

接下来, 如Giorgi所述 ,更正您的for循环。

就是说,不要使用gets() ,它会遇到缓冲区溢出问题。 使用fgets()代替。

  for (i=length-1;i<=0;i--)

由于i<=0 ,它将永远不会运行(除非字符串是0或1个字符长),可能应该是i>=0

通常,还需要使指针指向一些有效内存,以便能够取消引用它。 在您的情况下,您可能应该使用malloc分配足够的字节数,并将其结果分配给str1 然后,您可以在执行操作时对其进行写操作。

在您的函数中,您没有初始化c

int i,length,c;

并在for循环中使用它

*(str1+c) = *(str+i);

还有其他问题。

1)函数内部的str1未分配内存。

2)此循环将永远不会执行,因为for (i=length-1;i<=0;i--)中的条件永远不会为真(除非字符串为0或1个字符长)。

3)不要使用gets() ,它已被弃用。 而是使用fgets()

  1. 您没有在strrev()初始化str1
  2. 如果输入长度为2个字符或更多的字符串,则i<=0为假,并且不会执行for循环内的块。
  3. *(str1+c) ='\\0'; 会导致崩溃,因为str1的值不确定,并且str1指向某个有效位置的机会很小。

UPD: strrev() c也未初始化,这引起一些麻烦。

您尝试做的是不反转字符串。 程序中两个字符串都不会反转。 您试图以相反的顺序将一个字符串复制到另一个字符串中。

因此,要以相反的顺序复制原始字符串的sring应该有足够的空间来存储复制的字符。

但是在你的职能

char* strrev(char *str)
{
  char *str1
  //...

指针str1尚未初始化,并且没有指向适当大小的内存范围。

因此,您的程序具有未定义的行为。

还应考虑到功能gets是不安全的,并且C标准不再支持该功能。 请改用功能fgets

如果您的编译器支持可变长度数组(VLA),则程序可以采用以下方式

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

char * reverse_copy( char *s2, const char *s1 )
{
    size_t n = strlen( s1 );
    size_t i = 0;

    for ( ; i < n; i++ ) s2[i] = s1[n-i-1];

    s2[i] = '\0';

    return s2;
}

int main( void )
{
    char s1[1000];

    printf( "Please enter a String: " );
    fgets( s1, sizeof( s1 ), stdin );

    size_t n = strlen( s1 );

    if ( n != 0 && s1[n-1] == '\n' ) s1[n-1] = '\0';

    char s2[n + 1];

    puts( s1 );
    puts( reverse_copy( s2, s1 ) );

    return 0;
}

例如输入

Hello Asfakul Islam

然后输出看起来像

Please enter a String: Hello Asfakul Islam
Hello Asfakul Islam
malsI lukafsA olleH

否则,如果您的编译器不支持VLA,则需要动态分配适当大小的数组。 在这种情况下,程序可以例如通过以下方式查找

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

char * reverse_copy( char *s2, const char *s1 )
{
    size_t n = strlen( s1 );
    size_t i = 0;

    for ( ; i < n; i++ ) s2[i] = s1[n-i-1];

    s2[i] = '\0';

    return s2;
}

int main( void )
{
    char s1[1000];

    printf( "Please enter a String: " );
    fgets( s1, sizeof( s1 ), stdin );

    size_t n = strlen( s1 );

    if ( n != 0 && s1[n-1] == '\n' ) s1[n-1] = '\0';

    char *s2 = malloc( ( n + 1 ) * sizeof( char ) );

    puts( s1 );
    puts( reverse_copy( s2, s1 ) );

    free( s2 );

    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM