简体   繁体   English

在C中实现反向功能时出现分段错误

[英]Segmentation fault while implementing reverse function in C

I decided to make a reverse(s) function in C and in the process, I encountered 2 warning messages during compilation. 我决定在C语言中制作一个reverse(s)函数,在此过程中,我在编译过程中遇到了2条警告消息。

alexander@debian:~/Dropbox/GitRepo/M2MPL/text$ make reverse
cc     reverse.c   -o reverse
reverse.c: In function 'reverse':
reverse.c:29:2: warning: return makes integer from pointer without a cast [enabled by default]
reverse.c:29:2: warning: function returns address of local variable [enabled by default]
alexander@debian:~/Dropbox/GitRepo/M2MPL/text$ 

Since they were warnings I tried to ignore them and run the program, when I input an array of characters Dropbox using scanf("%s", str1); 由于它们是警告,因此当我使用scanf("%s", str1);输入字符数组Dropbox时,我试图忽略它们并运行程序scanf("%s", str1); , the result appeared as Segmentation Fault . 结果显示为Segmentation Fault

alexander@debian:~/Dropbox/GitRepo/M2MPL/text$ ./reverse
Enter a string to reverse: Dropbox
Segmentation fault
alexander@debian:~/Dropbox/GitRepo/M2MPL/text$ 

Here's my implementation of the reverse(s) function: 这是我对reverse(s)函数的实现:

/* reverse: returns a reversed string of s */
char reverse(char s[])
{
    int i, len=strlen(s);
    char result[LIMIT];

    for (i = len; i >= 0; --i) {
            result[len-i] = s[i];
    }

        return result;
}

FULL CODE HERE! 完整代码在这里!

I need help to know why I got a Segmentation fault instead of xobporD as a result and if possible, a suggestion to fix this problem. 我需要帮助来了解为什么我得到了Segmentation fault而不是xobporD Segmentation fault ,如果可能的话,还提出了解决此问题的建议。

First of all: 首先:
The compiler does not warn you just for fun. 编译器不会仅仅出于娱乐目的而警告您。 You shouldn't be surprised that your program crashes if you ignore compiler warnings. 如果您忽略编译器警告,则程序不会崩溃,您不会感到惊讶。

You return the pointer to an automatic variable that goes out of scope at the end of the function. 您将指针返回到在函数末尾超出范围的自动变量。 The pointer returned to the caller is not valid since it points to an object that no longer exists after the reverse function returns. 返回给调用方的指针无效,因为它指向reverse函数返回后不再存在的对象。

Another problem is that the first character that you copy is the '\\0' so your resulting string is empty. 另一个问题是,您复制的第一个字符为'\\0'因此您得到的字符串为空。 You need to reverse the characters of the string, but still put the '\\0' at the end of the string. 您需要反转字符串的字符,但仍将'\\0'放在字符串的末尾。

The first warning means that the return type indicated by the signature of the reverse function does not match the type of the variable that you are actually returning. 第一个警告意味着由reverse函数签名指示的返回类型与您实际返回的变量的类型不匹配。 The expected type is char , and you are returning a char * (because result decays to such a pointer). 预期的类型为char ,并且您将返回一个char * (因为result会衰减到这样的指针)。 So the compiler transforms the pointer into an integer ( char ), which is usually not what's intended by the programmer. 因此,编译器将指针转换为整数( char ),这通常不是程序员想要的。

The second problem is that you are returning the address of a local variable, and that variable is no longer available after the function returns, because of the way automatic storage works. 第二个问题是您正在返回局部变量的地址,并且由于自动存储的工作方式,该变量在函数返回后不再可用。 If you want to return a pointer to some data, it must be allocated either globally (declared static inside the function or declared globally), or it must be dynamically allocated. 如果要返回指向某些数据的指针,则必须全局分配(在函数内部声明为static或全局声明),或者必须动态分配。

There are a few flaws in the question code. 问题代码中存在一些缺陷。

  • It is likely that the return type should be 'char *' rather than 'char'. 返回类型可能应该是'char *'而不是'char'。
  • Attempting to return local stack memory to the caller. 尝试将本地堆栈内存返回给调用方。
  • The result string is likely missing a string termination character. 结果字符串可能缺少字符串终止字符。

The following code fix the above. 以下代码修复了上述问题。 It returns the string in allocated 'heap' memory to the caller. 它将分配的“堆”内存中的字符串返回给调用方。 (The caller should free() the memory when it is no longer needed.): (当不再需要内存时,调用者应释放()内存。):

/* reverse: returns a reversed string of s */
char *reverse(char *s)
   {
   int i, len=strlen(s);
   char *result = malloc(len+1);
   if(result)
      {
      result[len] = '\0';
      for(i = len; i >= 0; --i)
         result[len-i] = s[i];
      }

   return(result);
   }

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

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