0

I am sorry if I may not have phrased the question correctly, but in the following code:

int main() {
char* a=new char[5];
a="2222";
a[7]='f';     //Error thrown here
cout<<a;
}

If we try to access a[7] in the program, we get an error because we haven't been assigned a[7].

But if I do the same thing in a class :

class str
{
public:
    char* a;
    str(char *s) {
        a=new char[5];
        strcpy(a,s);
    }
};
int main()
{
    str s("ssss");
    s.a[4]='f';s.a[5]='f';s.a[6]='f';s.a[7]='f';
    cout<<s.a<<endl;
    return 0;
}

The code works, printing the characters "abcdfff". How are we able to access a[7], etc in the code when we have only allocated char[5] to a while we were not able to do so in the first program?

Sid Verma
  • 536
  • 1
  • 7
  • 25

4 Answers4

3

In your first case, you have an error:

int main() 
{
    char* a=new char[5];   // declare a dynamic char array of size 5
    a="2222"; // assign the pointer to a string literal "2222" - MEMORY LEAK HERE
    a[7]='f';     // accessing array out of bounds!
    // ...
}

You are creating a memory leak and then asking why undefined behavior is undefined.

Your second example is asking, again, why undefined behavior is undefined.

Zac Howland
  • 15,777
  • 1
  • 26
  • 42
1

As others have said, it's undefined behavior. When you write to memory out of bounds of the allocated memory for the pointer, several things can happen

  1. You overwrite an allocated, but unused and so far unimportant location
  2. You overwrite a memory location that stores something important for your program, which will lead to errors because you've corrupted your own memory at that point
  3. You overwrite a memory location that you aren't allowed to access (something out of your program's memory space) and the OS freaks out, causing an error like "AccessViolation" or something

For your specific examples, where the memory is allocated is based on how the variable is defined and what other memory has to be allocated for your program to run. This may impact the probability of getting one error or another, or not getting an error at all. BUT, whether or not you see an error, you shouldn't access memory locations out of your allocated memory space because like others have said, it's undefined and you will get non-deterministic behavior mixed with errors.

reblace
  • 4,115
  • 16
  • 16
1
int main() {
  char* a=new char[5];
  a="2222";
  a[7]='f';     //Error thrown here
  cout<<a;
}

If we try to access a[7] in the program, we get an error because we haven't been assigned a[7].

No, you get a memory error from accessing memory that is write-protected, because a is pointing to the write-only memory of "2222", and by chance two bytes after the end of that string is ALSO write-protected. If you used the same strcpy as you use in the class str, the memory access would overwrite some "random" data after the allocated memory which is quite possibly NOT going to fail in the same way.

It is indeed invalid (undefined behaviour) to access memory outside of the memory you have allocated. The compiler, C and C++ runtime library and OS that your code is produced with and running on top of is not guaranteed to detect all such things (because it can be quite time-consuming to check every single operation that accesses memory). But it's guaranteed to be "wrong" to access memory outside of what has been allocated - it just isn't always detected.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
1

As mentioned in other answers, accessing memory past the end of an array is undefined behavior, i.e. you don't know what will happen. If you are lucky, the program crashes; if not, the program continues as if nothing was wrong.

C and C++ do not perform bounds checks on (simple) arrays for performance reasons.

The syntax a[7] simply means go to memory position X + sizeof(a[0]), where X is the address where a starts to be stored, and read/write. If you try to read/write within the memory that you have reserved, everything is fine; if outside, nobody knows what happens (see the answer from @reblace).

nplatis
  • 432
  • 2
  • 8