3

这是教科书的 C 代码

void strcpy_new(char *s, char *t) {
    while ((*s = *t) != '\0') {
        s++;
        t++;
    }
}

int main(int argc, const char * argv[])
{

    char *s = "this is line a";
    char *t = "this is line b";
    printf("%s", s);
    strcpy_new(s, t);
    printf("%s", s);
    return 0;
}

当我用 Xcode 运行它时,我得到了 EXEC_BAD_ACCESS。

4

4 回答 4

5

您获得 EXEC_BAD_ACCESS 的原因是因为这些字符串文字存储在只读内存中"this is line a""this is line b"尝试写入它 ( *s = *t) 是未定义的行为,因此您会收到崩溃。

要修复此代码,您应该为其分配一些内存,s以便它足够大以容纳第二个字符串 ( t):

    char s[] = "this is line a"; // contrived example, s and t are the same length
    char *t = "this is line b";
    strcpy_new(s, t);
于 2012-09-26T02:39:44.777 回答
2

我敢打赌,您正在尝试使用字符串文字strcpy_new的目的地运行char *s

#include <string.h>

int main(int argc, char *argv[])
{
    char *a = "Some String";
    char *b = "Another string";
    strcpy(b, a);
    return 0;
}

将给出一个 EXEC_BAD_ACCESS。但是,以下内容不会

#include <string.h>

int main(int argc, char *argv[])
{
    char *a = "Some String";
    char b[] = "Another string";
    strcpy(b, a);
    return 0;
}

不同之处在于,在第一种情况下,它b指向__TEXT,__cstring,cstring_literals可执行文件部分中的一块内存,这是写保护的。在第二种情况下,它指向堆栈上的一块内存。

于 2012-09-26T02:54:13.413 回答
1

问题是覆盖字符串文字的效果是未定义的。

char *s = "this is line a";
char *t = "this is line b";
strcpy_new(s, t);

s并且t都在代码的数据部分中关闭,并且您的特定设置恰好EXEC_BAD_ACCESS在您尝试更改它们时给您一个。

于 2012-09-26T02:41:34.853 回答
1

字符串文字是只读的。在这里可以找到一个很好的答案:http ://ubuntuforums.org/showthread.php?t=357869

C 中的字符串文字是只读的。在您的示例代码中,“我的字符串”是一个字符串文字。

str[] 声明将文字复制到可写内存(堆栈或堆)中。因此,您的程序可以修改该字符串。

* 声明初始化一个指向文字本身的指针,因此您有一个指向只读段的指针。如果您尝试覆盖它,您将获得 SEGV。

于 2012-09-26T03:06:10.087 回答