EXC_BAD_ACCESS 在用 poitner 分配字符时发生

EXC_BAD_ACCESS occurred when assign char with a poitner

本文关键字:字符 分配 poitner BAD ACCESS 在用 EXC      更新时间:2023-10-16

EXC_BAD_ACCESS发生在*str++ = *end;年。这是怎么回事?

#include <iostream>
using namespace std;
int main() {
    char *hello = "abcdefgh";
    char c = 'c';
    char *str = hello;
    //printf("%s",str);
    char * end = str;
    char tmp;
    if (str) {
        while (*end) {
            ++end;
        }
        --end;
        while (str < end) {
            tmp = *str;
            printf("hello:%s str:%c, end:%cn", hello, *str, *end);
            *str++ = *end;
            *end-- = tmp;
        }
    }
    return 0;
}

尝试更改字符串文本是未定义的行为。 将您的代码更改为下面的等效代码,您将看到问题:

const char *hello = "abcdefgh";
const char *str = hello;
const char * end = str;

那么你明白为什么线路*str++ = *end;有问题吗? 您正在尝试写入const区域,但无法执行此操作。

如果你想要一个更简单的例子:

int main()
{
  char *str = "abc";
  str[0] = 'x';
}

如果这个简单的程序在

str[0] = 'x';

行被执行。

不幸的是,字符串文字不必在C中声明为const char*C++带来了这种语法。 因此,即使看起来您没有使用const,您也是。

如果您希望代码实际工作,请声明一个可写缓冲区,即 char 的array

char hello[] = "abcdefgh";
char str[100];
strcpy(str, hello);
char end[100];
strcpy(end, str);

似乎您正在尝试反转字符串。看起来你把事情复杂化了。

在堆栈上声明的C样式字符串必须声明为const char *,这意味着你不能更改字符,因为它们是常量。

在C++我们使用字符串和字符串迭代器:

#include <iostream>
#include <string>
using std::string;
using std::reverse;
using std::swap;
using std::cout;
using std::endl;
int main(int argc, const char * argv[])
{
    string hello("abcdefgh");
    reverse(hello.begin(), hello.end());
    cout << hello << endl;
    return 0;
}

手动地:

static void reverse(std::string & str)
{
    string::size_type b = 0, e = str.length() - 1, c = e / 2;
    while(b <= c)
    {
        swap(str[b++], str[e--]);
    }
}

递 归:

static void reverse_helper(std::string & str,
                            string::size_type b,
                            string::size_type e)
{
    if(b >= e)
        return;
    swap(str[b], str[e]);
    reverse_helper(str, ++b, --e);
}
static void reverse(std::string & str)
{
    reverse_helper(str, 0, str.length() - 1);
}