2010-11-19 64 views
4

比方说,返回的字符串是这样写C/C++字符指针崩溃

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

一个固定的“随机文本”功能,则程序可能崩溃,如果不小心改变做价值

Function1()[1]=’a’; 

函数调用尝试这样做会导致程序崩溃后,方括号是什么?如果您熟悉这一点,任何解释将不胜感激!

+1

[1]指向字符串中的第二个字符([0]将是第一个字符) – climbage 2010-11-19 16:10:07

+0

为什么在标题中说C++,但标记问题C? – GManNickG 2010-11-19 17:03:10

+1

你应该把这个标记为MSVC,因为gcc(至少> = 4)会警告你将一个char const []赋值给一个char *已被废弃......出于充分理由,如你所见。 – mmmmmmmm 2010-11-19 17:54:56

回答

12

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

这种情况通常是因为字符串本身是与应用程序的代码一起硬编码的。加载时,指针被建立以指向您的进程中只保留文字字符串的只读部分。实际上,每当你在C中写入一些字符串时,它将被视为const char*(指向常量内存的指针)。

+4

你不能说它会导致访问冲突。 C++不知道有关访问冲突的信息。你所能说的只是它会引起未定义的行为 – 2010-11-19 16:23:14

+1

@John:你说得对。以哲学含义为准:) – 2010-11-19 16:27:24

+0

@John:也许“will”太串了,但你很有可能会这样做:-) – mmmmmmmm 2010-11-19 17:56:35

0

这不是括号,而是分配。你的函数不是简单的char *,而是const char *(我在这里可能是错误的,但是这里的内存是只读的),所以你试图改变不可更改的内存。和括号 - 他们只是让你访问数组的元素。

1

你可以使用静态字符串作为返回值,但你永远不会使用它。这就像访问违规错误。它的行为没有在C++ Standard中定义。

+0

当然你可以*使用*它。你不能修改它的内容。 – 2010-11-19 16:18:30

+0

ohya,正好。还有一件事(就像工作...... :),就像许多其他人已经说过的那样,将常量字符串转换为非常量字符串是等等等等......你知道〜 – 2010-11-19 16:26:12

4

该功能的签名应该确实是constchar* Function();

+0

完全同意。 – 2010-11-19 16:15:29

+1

它实际上应该是'std :: string',因为OP想要修改从函数返回的值 – 2010-11-19 16:23:54

+0

是的,John,在C++中 - 当然,在C中 - 这是唯一的方法。 – 2010-11-19 17:02:37

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() reuturns,那么你将不得不做其他事情。我会使用一个类:

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

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

还要注意的是,你可以通过将文本规则阵列避免碰撞:

char Function1Str[] = "Some text"; 

char *Function1() 
{ 
    return Function1Str; 
} 
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)将是一种很好的做法,但是对于您而言,您可能是一个相当陡峭的学习曲线。