【问题标题】:strlen: Address out of bounds leading to segmentation faultstrlen:地址越界导致分段错误
【发布时间】:2013-01-28 02:53:26
【问题描述】:

我正在尝试在 C 中执行几个简单的 string_reverse 实现。但是,当我在 gdb 中调试时出现以下错误:

Program received signal SIGSEGV, Segmentation fault.
0x00000000004005ca in string_reverse1 (string=0x68 <Address 0x68 out of bounds>)
28          length = strlen(*string);
Missing separate debuginfos, use: debuginfo-install glibc-2.15-58.fc17.x86_64

这是我遇到的错误的代码(我在错误所在的行上发表了评论):

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

int main(int argc, char *argv[])
{
    char *char1 = "hello";
    char *char2 = "hi";
    char *char3 = "this is a really long string!";

    string_reverse1(*char1);
    string_reverse1(*char2);
    string_reverse1(*char3);
    printf("%s, %s, %s\n", char1, char2, char3);

    return 0;
}

//Assuming method's purpose is to reverse the passed string
//and set the original string equal to the reversed one
void string_reverse1(char *string) 
{
    //Calculate length once so it isn't recalculated at
    //every iteration of the for loop
    int length;
    char *reversed;
    int i;
    int reversed_counter;
    length = strlen(*string); //ERROR
    reversed_counter = 0;
    for(i = length - 1; i >= 0; i--) {
        reversed[reversed_counter] = string[i];
        reversed_counter++;
    }
    //Can't forget to add the terminating null character!
    reversed[length] = '\0';
    string = reversed;
}

我知道 strlen 通过遍历字符串返回传递字符串的长度,直到它到达 \0,即空字节。所以我想知道传递的字符串是否以某种方式不是以空值结尾的?我不认为我在 main 中错误地声明了字符串。

感谢您的任何见解。

【问题讨论】:

    标签: segmentation-fault strlen


    【解决方案1】:

    问题是当你打电话给string_reverse1:

    string_reverse1(*char1);
    

    char1 之前的 * 取消引用 char1 返回字符串第一个字符的值。如果你想传递*char,你应该忽略*。这是因为char1 的类型已经是char *。无需更改。

    当您取消引用 char1 时,您发送的是第一个字符“h”的实际 ascii 值。然后strlen 尝试访问地址“h”处的内存并出现段错误,因为那只是一些任意内存位置。

    【讨论】:

    • 太棒了,谢谢!这就说得通了。当我将字符串传递给 strlen 时,我还取出了 *,现在它可以正常工作了。
    【解决方案2】:

    而不是...

    string_reverse1(*char1);
    

    ...这样做:

    string_reverse1(char1);
    

    您的字符串定义已经是指针,所以这就是您需要传入的内容。取消引用它们会得到一个根本不是内存地址的值。

    【讨论】:

      【解决方案3】:

      根据您的声明 void string_reverse1(char *string),

        length = strlen(*string); //ERROR
      

      应该改为

         length = strlen(string); 
      

      主程序应该调用函数

      string_reverse1(char1);
      string_reverse1(char2);
      string_reverse1(char3);
      

      然后出现错误

      reversed[reversed_counter] = string[i];

      因为你没有为你的角色分配空间(分段错误通常是由于访问未分配的内存造成的。

      解决这个问题的一种方法是使用

      char* reversed = (char*) malloc(sizeof(char)*(length+1));
      

      这段代码你仍然会遇到问题,因为

      string = reversed;
      

      实际上并没有改变“字符串”的内容。你可以改变函数的工作方式来解决这个问题。更好的方法是更改​​“字符串”本身中的字符,而不是使用另一个数组。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-28
        • 1970-01-01
        • 2016-11-14
        • 2016-08-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多