1

I am extremely new to C++ and pointers.

#include <iostream>

using namespace std;

int main() {
    char* c = "my name jeff";
    int i = 0;
    while (true) {
        cout << *(c + i++);
    }
    return 0;
}

The output is "my name jeff" followed by a lot of random characters, occasionally making sense. Am I actually accessing memory in my computer ? Why can initialize a pointer from a string ?

Coral Kashri
  • 3,436
  • 2
  • 10
  • 22
  • 2
    The behaviour is undefined, so you can epect [nasal demons](http://catb.org/jargon/html/N/nasal-demons.html) if you do that. – Yksisarvinen Oct 16 '19 at 16:01
  • 3
    If you run a program inside an OS, you cannot access memory which wasn't assigned by your kernel to your program. If you write a kernel module, you should be able to access anywhere in memory, from that kernel module. Etc... It only depends where you program is supposed to be running. – Pierre Emmanuel Lallemant Oct 16 '19 at 16:06
  • `char* c = "my name jeff";` is invalid, it should be `const char* c = "my name jeff";`. – Jarod42 Oct 16 '19 at 16:23
  • The C++ standard imagines an abstract machine, to which the rules of C++ apply. Compiler makers convert the C++ source to an executable format suitable for your platform. The parts of the C++ language that explicitly or implicitly declare as undefined behavior means the compiler makers are at liberty to assume those things don't happen (usually for optimization purposes). So if your code doesn't follow the rules, ANYTHING could happen. Including destroying the planet. Which is bad. – Eljay Oct 16 '19 at 16:33
  • Code like this is a big reason why protected-mode operating systems work they way they do. Preventing you from accessing "all memory". You tend to get bored looking at the wildly scrolling output before the OS decides to terminate the program because it is trying to read from a non-mapped address. – Hans Passant Oct 16 '19 at 16:36

2 Answers2

2

From https://eel.is/c++draft/expr#add-4

When an expression J that has integral type is added to or subtracted from an expression P of pointer type, the result has the type of P.

(4.1) If P evaluates to a null pointer value and J evaluates to 0, the result is a null pointer value.

(4.2) Otherwise, if P points to an array element i of an array object x with n elements ([dcl.array]),77 the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) array element i + j of x if 0 ≤ i + j ≤ n and the expression P - J points to the (possibly-hypothetical) array element i − j of x if 0 ≤ i − j ≤ n .

(4.3) Otherwise, the behavior is undefined.

So, with "my name jeff" (which is of type const char[13] (with the extra '\0')), once you do c[14] you have UB.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • Even though it should be noted, with the fact that C/C++ are system programming languages, that it is totally not undefined behavior if you set a pointer to an arbitrary address, for example if you want to access registers located there in an embedded system. So, the compiler makers are not really at liberty to prevent such things as it would defeat the purpose. – BitTickler Oct 16 '19 at 21:54
1

First, a note about this line right here:

char* c = "my name jeff";

In modern C++, this should be a const instead:

const char* c = "my name jeff";

With that out of the way, the answer to your question is yes and no.

Yes in the sense that if you have some sort of pointer, C++ doesn't care what you put in it.

char * pointer = nullptr;
char a, b, c;

pointer = &a;
pointer = &b;
pointer = &c;

The pointer doesn't care what address is stored in it. It is arbitrary in that sense. As long as it is the same type, you're fine.

You can even do pointer arithmetic like this:

*(pointer + 1) = 1;
*(pointer + 2) = 2;
*(pointer + i) = i;

In most cases, this will usually at least compile and probably run. In theory, you could use this type of arithmetic to access any given address and see what data is stored there.

However, in practice, the answer is a big no. That is because accessing unallocated memory is undefined behavior in C++. If you're unaware, undefined behavior allows anything to happen, including crashing or printing weird characters.

So, if you have some array like this:

int arr[4] = {1,2,3,4};
int * pointer = arr;

std::cout << *(pointer + 7);

This is undefined behavior because only pointer + 3 is guaranteed to have allocated memory in it.

So, in short: Yes, you can theoretically reach any address you want with pointer arithmetic, but you can only access memory that has been allocated safely. So in practice, not really.

  • Oh I just realised that const char* is basically a string. Thanks – Bino Manjesh Oct 17 '19 at 09:39
  • Sort of. There is such a thing as an [`std::string`](https://en.cppreference.com/w/cpp/string/basic_string), which is what C++ usually thinks of as a string. But a `const char *` is close. You can read about it more in [this question](https://stackoverflow.com/q/1287306/10957435). –  Oct 17 '19 at 17:06