【问题标题】:Segmentation fault while implementing reverse function in C在 C 中实现反向功能时出现分段错误
【发布时间】:2014-06-02 07:39:22
【问题描述】:

我决定在 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$ 

由于它们是警告,我试图忽略它们并运行程序,当我使用scanf("%s", str1); 输入字符数组Dropbox 时,结果显示为Segmentation Fault

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

这是我对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!

我需要帮助来了解为什么我得到了 Segmentation fault 而不是 xobporD,如果可能的话,我需要一个解决此问题的建议。

【问题讨论】:

    标签: c function segmentation-fault return warnings


    【解决方案1】:

    首先:
    编译器不会仅仅为了好玩而警告您。如果您忽略编译器警告,您应该不会对程序崩溃感到惊讶。

    您将指针返回到函数末尾超出范围的自动变量。返回给调用者的指针无效,因为它指向的对象在reverse 函数返回后不再存在。

    另一个问题是你复制的第一个字符是'\0',所以你得到的字符串是空的。您需要将字符串的字符反转,但仍将'\0' 放在字符串的末尾。

    【讨论】:

      【解决方案2】:

      第一个警告意味着reverse 函数的签名所指示的返回类型与您实际返回的变量的类型不匹配。预期的类型是char,而您返回的是char *(因为result 衰减到这样的指针)。所以编译器将指针转换为一个整数(char),这通常不是程序员想要的。

      第二个问题是你返回的是一个局部变量的地址,而在函数返回后,该变量不再可用,因为自动存储的工作方式。如果要返回指向某些数据的指针,则必须全局分配(在函数内部声明 static 或全局声明),或者必须动态分配。

      【讨论】:

        【解决方案3】:

        问题代码中存在一些缺陷。

        • 返回类型很可能应该是“char *”而不是“char”。
        • 正在尝试将本地堆栈内存返回给调用方。
        • 结果字符串可能缺少字符串终止字符。

        以下代码修复了上述问题。它将分配的“堆”内存中的字符串返回给调用者。 (调用者应该在不再需要内存时释放()内存。):

        /* 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);
           }
        

        【讨论】:

        • 我还不知道char * 以及C 如何处理内存,所以我使用char。我会尝试使用它。
        猜你喜欢
        • 2020-06-01
        • 1970-01-01
        • 2022-10-19
        • 2020-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-10
        • 1970-01-01
        相关资源
        最近更新 更多