在反转字符串时获取“分段故障核心转储错误”

时间:2015-11-04 12:45:02

标签: c string algorithm pointers segmentation-fault

我正在尝试学习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;

}

5 个答案:

答案 0 :(得分:2)

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

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

接下来,as Giorgi mentioned,更正你的for循环。

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

答案 1 :(得分:2)

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

由于i<=0,这将永远不会(除非字符串长度为0或1个字符),应该i>=0

通常,您还需要使指针指向某个有效的内存,以便能够取消引用它。在您的情况下,您应该使用malloc来分配足够数量的字节,并将其结果分配给str1。然后你可以像往常一样写信给它。

答案 2 :(得分:0)

在您的函数中,您没有初始化SELECT u.ID, u.user_login, u.user_registered, u.display_name FROM ( SELECT user_id, MAX(create_date) AS max_create_date FROM purchase_key WHERE product_id IN (1, 2) AND create_date BETWEEN '2014-09-01' AND '2015-09-20' GROUP BY user_id ) p INNER JOIN users u ON p.user_id = u.id ORDER BY p.max_create_date ASC

c

并在int i,length,c; 循环

中使用它
for

还有其他问题..

1)函数内的*(str1+c) = *(str+i); 没有分配内存。

2)此循环永远不会被执行,因为str1中的条件永远不会为真(除非字符串为0或1个字符长)。

3)不要使用for (i=length-1;i<=0;i--),不推荐使用它。而是使用gets()

答案 3 :(得分:0)

  1. 您未在str1
  2. 中初始化strrev()
  3. 如果输入长度为2个字符或更长的字符串,则i<=0为false,并且for循环内的块不会被执行。
  4. *(str1+c) ='\0';会导致崩溃,因为str1的值是不确定的,str1指出某个有效位置的可能性很小。
  5. UPD:c中的strrev()也未初始化,造成一些麻烦。

答案 4 :(得分:0)

您要做的不是反转字符串。程序中的字符串都没有反转。您试图以相反的顺序在另一个字符串中复制一个字符串。

因此,您要以相反的顺序复制原始字符串的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;
}