C / C ++ Char指针崩溃

时间:2010-11-19 16:05:00

标签: c++ c pointers crash

假设一个返回固定“随机文本”字符串的函数就像

一样
char *Function1()
{ 
return “Some text”;
}

然后程序可能会崩溃,如果它意外地试图改变值

Function1()[1]=’a’;

函数调用尝试执行此操作后的方括号会导致程序崩溃吗?如果您对此很熟悉,我们将非常感谢您的解释!

7 个答案:

答案 0 :(得分:12)

您在函数中返回的字符串通常存储在进程的只读部分中。尝试修改它将导致访问冲突。 (编辑:严格来说,它是未定义的行为,在某些系统中它会导致访问冲突。谢谢,John)。

这种情况通常是因为字符串本身与应用程序的代码一起被硬编码。加载时,会建立指针以指向包含文字字符串的进程的只读部分。实际上,无论何时在C中编写一些字符串,它都被视为const char*(指向const内存的指针)。

答案 1 :(得分:4)

该功能的签名应该是 const char* Function();

答案 2 :(得分:3)

您正在尝试修改字符串文字。根据标准,这唤起了undefined behavior。要记住的另一件事(相关)是字符串文字总是const char*类型。将指向字符串文字的指针转换为char*有一个特殊的特权,取消const限定符,但底层字符串仍然是const 。因此,通过执行您正在执行的操作,您尝试修改const。这也会引起未定义的行为,类似于尝试这样做:

const char* val = "hello";
char* modifyable_val = const_cast<char*>(val);
modifyable_val[1] = 'n';  // this evokes UB

不是从函数返回const char*,而是按值返回string。这将基于字符串文字构造一个新的string,并且调用代码可以做任何想做的事情:

#include <string>

std::string Function1()
{ 
return “Some text”;
}

...后:

std::string s = Function1();
s[1] = 'a';

现在,如果您尝试更改Function()重新创建的值,那么您将不得不做其他事情。我会上课:

#include <string>
class MyGizmo
{
public: 
  std::string str_;
  MyGizmo() : str_("Some text") {};
};

int main()
{
  MyGizmo gizmo;
  gizmo.str_[1] = 'n';
}

答案 3 :(得分:1)

您可以使用静态字符串作为返回值,但绝不使用它。这就像访问冲突错误一样。它的行为未在c ++标准中定义。

答案 4 :(得分:0)

这不是括号,而是分配。你的函数返回的不是一个简单的char *,而是const char *(我可能在这里错了,但这里的内存是只读的),所以你试着改变不可更改的内存。括号 - 它们只是让您访问数组的元素。

答案 5 :(得分:0)

另请注意,您可以通过将文本放在常规数组中来避免崩溃:

char Function1Str[] = "Some text";

char *Function1()
{
    return Function1Str;
}

答案 6 :(得分:0)

问题表明你不理解字符串文字。

对此代码进行拍摄

char* pch = "Here is some text";
char* pch2 = "some text";
char* pch3 = "Here is";

现在,编译器如何为字符串分配内存完全是编译器的问题。记忆可能像这样组织:

Here is<NULL>Here is some text<NULL>

pch2指向pch字符串内的内存位置。

这里的关键是理解记忆。使用标准模板库(stl)是一个很好的做法,但对于你来说,你可能是一个非常陡峭的学习曲线。