【问题标题】:Replacing part of string with another string causes segfault用另一个字符串替换部分字符串会导致段错误
【发布时间】:2014-10-31 22:17:40
【问题描述】:

我想做一些简单的事情,但我一直在努力解决这个问题太久了。我有一个总是以特定“令牌”结尾的字符串。在“++”以下的情况下。我想用较短的标记替换结束标记,比如说“#”。

strstr 返回 NULL 或指向初始结束标记的指针。 strcpy 应该使用从strstr 返回的指针,并用“#\0”覆盖“++”。

至少我认为它应该这样做。相反,我得到一个“赋值使指针从没有强制转换的整数”警告。在这一点上,我已经尝试了strcpy(*newThing, "#"); 和其他一些东西。不给出错误的东西会导致段错误。

在这种情况下,C 是从堆栈上的一些不可变空间中获取原始字符串的存储空间吗?我需要使用“alloc”之一吗?我也试过了,但可能漏掉了什么。

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

int main() {
    char *thing="ssssssssssssssss++";
    char *newThing;

    newThing = strstr(thing, "++");
    strcpy(newThing, "#");
    printf("%s\n", thing);

    exit(0);
}

【问题讨论】:

  • 你不能修改 C 中的字符串文字(甚至不能修改数组以“替换”它的一部分)。
  • 使用strdup 将字符串文字替换为堆分配的副本,或将thing 定义为char thing[] 以将其分配在堆栈上。此外,您应该检查newThing 是否为NULL,而不是未选中将其传递给strcpy
  • 如果我将char *thing="ssssssssssssssss++"; 替换为char thing[]="ssssssssssssssss++";,一切正常。 ideone.com/IOPCAI

标签: c pointers strcpy string-literals


【解决方案1】:

您的问题是 thing 是一个指向字符串文字的指针。在过去,您可以这样做,但是当前的编译器将字符串文字存储在不可写的内存中。

因此,当您执行代码时,您会收到 访问冲突写入位置(或等效消息)。

解决这个问题的最简单方法:声明一个自动数组用字符串字面量初始化,一切都很好:

char thing[]="ssssssssssssssss++";

(数组和指针不完全一样……)

【讨论】:

    【解决方案2】:

    问题在于thing 是一个字符串文字。你可以使用这个:

    char thing[]="ssssssssssssssss++";

    它将分配所需的糊状空间(编译器将自动计算出数组的大小)。

    我搜索了字符串文字失败的原因。我找到了一个我忘记的例子。 Here 是。

    这几乎可以归结为:

    字符串字面量不能修改它们的数据,但它们可以修改它们的指针。另一方面,如果你有一个数组,那么情况正好相反。不能修改指针,但可以修改数据。

    对此有一个有趣的评论是:“字符串字面量有一个类型。它是字符数组。虽然你说“字符串文字不能修改它们的数据,但它们可以修改它们的指针”,但我的主要问题是它们没有你暗示的指针。指针和字符串字面量实际上是分开的。”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-25
      • 1970-01-01
      • 2022-12-28
      • 2011-08-10
      相关资源
      最近更新 更多