简体   繁体   English

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

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

I am trying to learn C, I am getting this error while reversing a string. 我正在尝试学习C,在反转字符串时遇到此错误。 I am not well versed with memory allocation stuffs, can you please point out where I am doing wrong. 我不太熟悉内存分配的东西,请您指出我做错的地方。

#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;

}

Inside your strrev() function, str1 is not allocated memory. 在您的strrev()函数中,未为str1分配内存。 Hence, *(str1+c) = *(str+i); 因此, *(str1+c) = *(str+i); is UB . UB

Then, c is an automatic local variable which is not initialized before use. 然后, c是一个自动局部变量,在使用前未初始化。 Also UB. 也UB。

Next, as Giorgi mentioned , correct your for loop. 接下来, 如Giorgi所述 ,更正您的for循环。

That said, don't use gets() , it suffers from buffer overrun issues. 就是说,不要使用gets() ,它会遇到缓冲区溢出问题。 Use fgets() instead. 使用fgets()代替。

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

This will never (unless string is 0 or 1 character long) run due to i<=0 , should be i>=0 probably. 由于i<=0 ,它将永远不会运行(除非字符串是0或1个字符长),可能应该是i>=0

Also in general you need to make pointer point to some valid memory in order to be able to dereference it. 通常,还需要使指针指向一些有效内存,以便能够取消引用它。 In your case you should probably use malloc for allocating sufficient number of bytes, and assign its result to str1 . 在您的情况下,您可能应该使用malloc分配足够的字节数,并将其结果分配给str1 Then you can write to it as you are doing. 然后,您可以在执行操作时对其进行写操作。

In your function, you did not initialize c 在您的函数中,您没有初始化c

int i,length,c;

and are using it inside the for loop 并在for循环中使用它

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

Plus other problems are there.. 还有其他问题。

1) str1 inside the function is not allocated memory. 1)函数内部的str1未分配内存。

2) This loop will never get executed, as the condition in for (i=length-1;i<=0;i--) is never true (unless string is 0 or 1 character long). 2)此循环将永远不会执行,因为for (i=length-1;i<=0;i--)中的条件永远不会为真(除非字符串为0或1个字符长)。

3) Do not use gets() , it is deprecated. 3)不要使用gets() ,它已被弃用。 Instead use fgets() 而是使用fgets()

  1. You don't initialize str1 in strrev() 您没有在strrev()初始化str1
  2. If you enter string whose length is 2 characters or more, i<=0 is false and the block inside the for loop won't be executed. 如果输入长度为2个字符或更多的字符串,则i<=0为假,并且不会执行for循环内的块。
  3. *(str1+c) ='\\0'; will cause the crash because the value of str1 is indeterminate and you have few chance that str1 points some valid place. 会导致崩溃,因为str1的值不确定,并且str1指向某个有效位置的机会很小。

UPD: c in strrev() is also uninitialized, and it will cause some trouble. UPD: strrev() c也未初始化,这引起一些麻烦。

What you are trying to do is not reversing a string. 您尝试做的是不反转字符串。 Neither string is reversed in your program. 程序中两个字符串都不会反转。 You are trying to copy one string in another string in the reverse order. 您试图以相反的顺序将一个字符串复制到另一个字符串中。

So the sring where you are going to copy the original string in the reverse order shall have enough space to store the copied characters. 因此,要以相反的顺序复制原始字符串的sring应该有足够的空间来存储复制的字符。

However in your function 但是在你的职能

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

pointer str1 was not initialized and does not point to an extent of memory of the appropriate size. 指针str1尚未初始化,并且没有指向适当大小的内存范围。

So your program has undefined behaviour. 因此,您的程序具有未定义的行为。

Take also in account that function gets is unsafe and is not supported by the C standard any more. 还应考虑到功能gets是不安全的,并且C标准不再支持该功能。 Use function fgets instead. 请改用功能fgets

If your compiler supports Variable Length Arrays (VLA) then the program can look the following way 如果您的编译器支持可变长度数组(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;
}

If to enter for example 例如输入

Hello Asfakul Islam

then the output will look like 然后输出看起来像

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

Otherwise if your compiler does not support VLA(s) you need to dynamically allocate an array of the appropriate size. 否则,如果您的编译器不支持VLA,则需要动态分配适当大小的数组。 In this case the program can look for example the following way 在这种情况下,程序可以例如通过以下方式查找

#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