开发者

C/C++ Char Pointer Crash

开发者 https://www.devze.com 2023-01-26 03:33 出处:网络
Let\'s say that a function which returns a fixed ‘random text’ string is written like char *Function1()

Let's say that a function which returns a fixed ‘random text’ string is written like

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

then the program could crash if it accidentally tried to alter the value doi开发者_JAVA技巧ng

Function1()[1]=’a’;

What are the square brackets after the function call attempting to do that would make the program crash? If you're familiar with this, any explanation would be greatly appreciated!


The string you're returning in the function is usually stored in a read-only part of your process. Attempting to modify it will cause an access violation. (EDIT: Strictly speaking, it is undefined behavior, and in some systems it will cause an access violation. Thanks, John).

This is the case usually because the string itself is hardcoded along with the code of your application. When loading, pointers are stablished to point to those read-only sections of your process that hold literal strings. In fact, whenever you write some string in C, it is treated as a const char* (a pointer to const memory).


The signature of that function should really be constchar* Function();.


You are trying to modify a string literal. According to the Standard, this evokes undefined behavior. Another thing to keep in mind (related) is that string literals are always of type const char*. There is a special dispensation to convert a pointer to a string literal to char*, taking away the const qualifier, but the underlying string is still const. So by doing what you are doing, you are trying to modify a const. This also evokes undefined behavior, and is akin to trying to do this:

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

Instead of returning a const char* from your function, return a string by value. This will construct a new string based on the string literal, and the calling code can do whatever it wants:

#include <string>

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

...later:

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

Now, if you are trying to change the value that Function() reuturns, then you'll have to do something else. I'd use a class:

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

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


You can use static char string for return value, but you never use it. It's just like access violation error. The behavior of it is not defined in c++ Standard.


It's not the brackets, but the assignement. Your function returns not a simple char *, but const char *( i can be wrong here, but the memory is read-only here), so you try to change the unchangeable memory. And the brackets - they just give you access to the element of the array.


Note also that you can avoid the crash by placing the text in a regular array:

char Function1Str[] = "Some text";

char *Function1()
{
    return Function1Str;
}


The question shows that you do not understand the string literals.

image this code

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

Now, how the compiler allocates memory to the strings is entirely a matter for the compiler. the memory might organised like this:

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

with pch2 pointing to memory location inside the pch string.

The key here is understanding the memory. Using the Standard Template Library (stl) would be a good practice, but you may be quite a steep learning curve for you.

0

精彩评论

暂无评论...
验证码 换一张
取 消