C/C++ Char Pointer Crash - c++

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 doing
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.

Related

Why does cout << *s << endl produce a segfault?

I have this question on a practice exam for my C++ class, we're supposed to write what the output is or if it produces an error. Running this code produces a segmentation fault, but can someone explain why? It looks fine to me.
string *s;
s = (string *) "This is my house. I have to defend it.";
cout << *s << endl;
Indirecting through a pointer of type std::string* when it doesn't point to an object of type std::string has undefined behaviour.
A string literal is not an object of type std::string. String literal is an array of characters. std::string is a class defined in the header <string>.
Running this code produces a segmentation fault, but can someone explain why?
You indirect through a pointer that doesn't point to an object of compatible type. The behaviour of your program is undefined.
P.S. It is never necessary to use C-style cast (such as (type)expression). It can easily suppress helpful compilation errors and replace them with undefined behaviour. It should be avoided.
If you hadn't used a C-style cast here, then the type system would have alerted you to the mistake before getting to run the program. In this case, you might have seen an error message similar to:
error: cannot convert 'const char [39]' to 'std::string*' {aka 'std::basic_string<char>*'} in assignment
helping you realise that the types do not match.
You need to learn the difference between a string literal and class std::string.
Casting a string literal to std::string* is undefined behaviour. Which manifests itself here as a segmentation fault when the code does *s because s is invalid.
Without that C-style cast (string *) in s = (string *) "T..."; the compiler would emit an error.
Always question those C-style casts in C++.
The likely problem (or at least one of the problems) is the fact that s has no memory allocated to it. You need to use the new keyword and try something like this:
string *s;
s = new string("This is my house. I have to defend it.");
cout << *s << endl;
Of course, in theory you'd need to use delete too.
std::string tends to boil down to something that looks like this:
struct string
{
char* _begin;
char* _end;
char* _capacity;
};
The text string you have defined would look like this:
const char* const text = "This is my house. I have to defend it."
So you are casting from type (char*), to type (string*). This now means that _begin will store the memory location "This is ", and _end will store the memory location "my house"
When printing the string to std::cout, it will dereference the pointer to s, and try to find the string size, usually implemented like so:
size_t string::size() const { return _end - _begin; }
Given that _begin and _end aren't storing pointer values (they are just random bits of text), this will result in cout trying to print a very wrong number of characters _(because the memory locations in _begin and end are a nonsense)

Passing a string to a char array, then modify the char array at position x in C

So I have a string which contains "RGGB" and I need it to be in a char array to perform some operations. Then I need to replace certain characters for a blank space, for example the first 'G', so that my char array remains "R GB".
How can I do this? So far I tried this solution:
int main()
{
string problem="RGGB";
const char *p=problem.c_str();
p[1]=' ';
return p;
}
I get the error:
assignment of read only location *(p + ((sizetype)i))
To access the "interal string" (I mean a const char*) of a std::string, there are two member functions provided: std::string::c_str and std::string::data. Until C++11, the difference was that std::string::data wasn't bound to return a pointer to a null-terminated const char* while std::string::c_str was. Now, they are equivalent. And both return a const char*, even before C++11.
There are several approaches to your problem:
Use std::strdup or std::str(n)cpy to duplicate the string and write to the duplicate.
Use a const_cast. Pretty drastic, but, if it doesn't hurt any rules (FYI, it does), works.
Don't use std::string at all. Do what you want with a char* and then optionally convert it to a std::string later.
Just use the functionality of std::string.
string, a C++ class, does not provide directly alterable access to its innerds via a char *. While you could cast away the const, this is dangerous because compilers may use the const as an optimization path.
If you absolutely need to do this just use a char array, not a string or alter the contents of the string using string methods.
p[1]=' ';
is not valid as const char * is read-only pointer.
in other words, it is a const pointer.
remember:
When const appears to the left of the *, what's pointed to is constant, and if const appears to the right of the *, the pointer itself is constant. If const appears on both sizes, both are constants.
this code might work:
char problem[]="RGGB";
char* p = problem;
p[1]=' ';
cout<<problem;
The answer is in your question:
I need it to be in a char array
Then put it in a char array:
char problem[] = "RGGB";
problem[1] = ' ';
Problem solved.
If, on the other hand, you want to solve the problem using actual C++:
std::string problem = "RGGB";
problem.at(1) = ' ';

Access violation at modifying char* by dereferencing [duplicate]

I read this on wikipedia
int main(void)
{
char *s = "hello world";
*s = 'H';
}
When the program containing this code is compiled, the string "hello world" is placed in the section of the program executable file marked as read-only; when loaded, the operating system places it with other strings and constant data in a read-only segment of memory. When executed, a variable, s, is set to point to the string's location, and an attempt is made to write an H character through the variable into the memory, causing a segmentation fault**
i don't know why the string is placed in read only segment.please someone could explain this.
String literals are stored in read-only memory, that's just how it works. Your code uses a pointer initialized to point at the memory where a string literal is stored, and thus you can't validly modify that memory.
To get a string in modifiable memory, do this:
char s[] = "hello world";
then you're fine, since now you're just using the constant string to initialize a non-constant array.
There is a big difference between:
char * s = "Hello world";
and
char s[] = "Hello world";
In the first case, s is a pointer to something that you can't change. It's stored in read-only memory (typically, in the code section of your application).
In the latter case, you allocate an array in read-write memory (typically plain RAM), that you can modify.
When you do: char *s = "hello world"; then s is a pointer that points to a memory that is in the code part, so you can't change it.
When you do: char s[] = "Hello World"; then s is an array of chars
that are on the stack, so you can change it.
If you don't want the string to be changed during the program, it is better to do: char
const *s = ....;. Then, when you try to change the string, your program will not crash with segmentation fault, it will arise a compiler error (which is much better).
first have a good understanding of pointers, I will give u a short demo:
First let us analyze your code line by line. Lets start from main onwards
char *s = "Some_string";
first of all, you are declaring a pointer to a char variable, now *s is a address in memory, and C will kick you if you try to change its memory value, thats illegal, so u better declare a character array, then assign s to its address, then change s.
Hope you get, it. For further reference and detailed understanding, refer KN King: C programming A Modern Approach
Per the language definition, string literals have to be stored in such a way that their lifetime extends over the lifetime of the program, and that they are visible over the entire program.
Exactly what this means in terms of where the string gets stored is up to the implementation; the language definition does not mandate that string literals are stored in read-only memory, and not all implementations do so. It only says that attempting to modify the contents of a string literal results in undefined behavior, meaning the implementation is free to do whatever it wants.

pointer to char array, unhandled exception

I'm new to C++ and I'm playing with pointers. I can't figure out why this piece of code doesn't work for me. Can you tell me what's wrong with it?
char * name = "dharman";
char *ptr = name+3;
*ptr = 'a';
printf("%s", name);
I get unhandled exception all the time.
This alone is an error:
char * name = "dharman";
The string is in constant memory but the pointer's type indicates it can be modified. Attempting to modify it produces undefined behavior: on other platforms the program will work but you got unlucky.
This was a quirk in C++03; the newer C++11 spec makes it illegal. The reason it was ever done was C compatibility.
Whether you're writing in C++ or plain C, the solution is simple:
char name[] = "dharman";
Now the compiler stores the data in read-write memory because you have asked for an array of char, not a pointer to some other memory.
String literals, like "dharman", are read-only and you cannot modify them. Instead, create and initialize an array that is not read only.
char name[] = "dharman";
name is a pointer to a string literal "dharman", which is located in read-only memory.
In your statement *ptr = 'a', you are trying to modify this string literal, which results in Undefined Behavior
It doesn't work because "dharman" is constant, it's a string literal. You cannont change it!
String literals are usually placed in read-only segments of memory.
You are trying to modify a constant string.
You need to copy the constant first to some memory that you own.
Try this:
char *name = (char*) malloc(10);
memcpy(name, "dharman", strlen("dharman"));
...
You are setting name to point at a const string and then trying to modify it. Copy the string to a modifiable location:
char *name = (char*) malloc(strlen("dharman") + 1);
memcpy("dharman", name, strlen("dharman") + 1);
The reason for unhandled exception in your case is.In your code
char *ptr= name+3;
consider the base address of name as eg:23300, so char *ptr =name+3 will be equal to
23300+(3*sizeof(char)).so now ptr points to 23300+(3*1)=23303.each element occupies one bye for char so ptr will point to letter 'a' in "dharman".since "dharman" is char const you can't its value that's why you are getting error.if u remove the line *ptr=3.the code will work without out any issue.I hope you find this post useful.

Allocating C-style string on the Heap

guys, I need a little technical help.
I'm working in C++, don't have much experience working in it but know the language somewhat. I need to use a C-style string (char array) but I need to allocate it on the heap.
If you look at this very simple piece of code:
#include <iostream>
using namespace std;
char* getText()
{
return "Hello";
}
int main()
{
char* text;
text = getText();
cout << text;
//delete text; // Calling delete results in an error
}
Now, I'm assuming that the "Hello" string is allocated on the stack, within getText(), which means the pointer will be "floating" as soon as getText returns, am I right?
If I'm right, then what's the best way to put "Hello" on the heap so I can use that string outside of getText and call delete on the pointer if I need to?
No, there's no hidden stack allocation going on there. "Hello" is static data, and ends up in the .data segment of your program.
This also means the string is shared for all calls to getText. A common use when this would be acceptable is if you have a large list of error messages that map to error codes. Functions like strerror work like this, so that you can get descriptive error messages for standard library error codes. But nobody is supposed to modify the return value of strerror (also because it is const). In your case, your function definition should read:
const char *getText()
If you do want a private copy of the string returned, you can use the strdup function to make a copy:
return strdup("Hello");
Use a std::string, from the <string> header. Then use its .c_str() member function. Then you don't have to care about allocation and deallocation: it takes care of it for you, correctly.
Cheers & hth.,
This is not right. "Hello" is a static string constant and it really should be const char*.
A narrow string literal has type "array of n const char", where n is the size of the string as defined below, and has static storage duration.
Static storage is neither automatic ("on the stack") nor dynamic ("on the heap"). It is allocated prior to the actual runtime of your program, so pointers to string literals never become invalid.
Note that char* p = "Hello" is deprecated because it is dangerous: the type system cannot prevent you from trying to change the string literal through p (which would result in undefined behavior). Use const char* p = "Hello" instead.