【问题标题】:Truncating string causes segmentation fault截断字符串会导致分段错误
【发布时间】:2017-08-02 06:44:13
【问题描述】:

我想用 C 语言编写一个函数,将输入字符串截断为 32 个字符,但下面的代码给了我一个分段错误。谁能解释一下为什么会这样?

void foo (char *value){
    if (strlen(value)>32) {
        printf("%c\n", value[31]); // This works
        value[31] = '\0';          // This seg faults
    }
}

【问题讨论】:

  • 向我们显示调用方代码。
  • 这只是我编写的更大功能的一小部分。我没有发布函数的其余部分,它在将值字符串传递给它时起作用。
  • 调用方代码就是:foo("hello");
  • 更改字符串字面量是非法的。
  • "调用方代码就是:foo("hello");" -- 您应该在启用警告的情况下编译您的代码,并注意它们。您的编译器很可能会警告将 "hello" 传递给需要(可修改)char* 参数的函数无效。

标签: c string char segmentation-fault truncate


【解决方案1】:

如果你这样调用你的函数:

char str[] = "1234567890123456789012345678901234567890";
foo(str);

它会正常工作的。但如果你这样称呼它:

char *str = "1234567890123456789012345678901234567890";
foo(str);

这可能会导致段错误。

这里的区别在于,在前一种情况下str 是一个char 数组,而在后一种情况下str 是一个指向字符串常量的指针。字符串常量通常位于内存的只读部分中,因此尝试修改它会导致核心转储。

【讨论】:

  • @HuiWang 很高兴我能帮上忙。如果您觉得有用,请随时 accept this answer
【解决方案2】:

你的程序应该是这样的:

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

void foo(char **value) {
    if (strlen(*value)>32) {
        printf("%c\n", (*value)[32]);
        (*value)[32] = '\0'; // You want the string length to be 32, so set 32th character to '\0' so 32 characters will be from 0 to 31
    }
}

int main() {
    char *str;
    str = malloc(100); // Change 100 to max possible length of string user can enter

    printf("Enter string : ");
    scanf("%s", str);

    foo(&str);

    printf("Truncated string is %s\n", str);

    free(str);

    return 0;
}

【讨论】:

  • 这正是你should not cast the result of malloc的原因之一。请参阅this answer 的最后一个要点。您忘记包含 stdlib.h 并且演员隐藏了错误。另外,free 内存(尽管在这种情况下它会在程序结束时自动释放)
  • @CoolGuy 自 C99 以来,演员表并没有隐藏错误
  • 这里需要注意的重要一点是你必须为 C++ 进行强制转换
  • @M.M 感谢您告诉我! :-)
猜你喜欢
  • 2015-09-03
  • 2012-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多