Home > Software engineering >  Access the memory beyond the pointer originally declared
Access the memory beyond the pointer originally declared

Time:10-12

I know we are not allowed to write the value in the memory place where beyond our pointers tied when the pointer declared. So the following code will compile error.

    int a = 2, b = 3, c = 4;
    int* d = &b;
    *(d 1)=6; //ERROR

However, then why in this case:

    char str[] = "hello";
    char* strB = &str[0];
    *(strB   1) = 'E';
    int i;
    for (i = 0; i < 400; i  ) {
        printf("%c\n", *(strB   i)); // hEllo followed by some trash value
    }

will work. Isn't there any problem in *(strB 1)=...? The pointer strB originally pointed to a char type; however, it seems illegal that strB can "see" or "write" the value stored in str[1], str[2], and so on. If, the pointer can access the region outside its legal region when that region is already owned by our program, then why did the first program not work? I think the address of d 1 will correspond to the place where the variable c or a live.

CodePudding user response:

I think you are just slightly confused on how pointers work. Hopefully I can clear things up for you. "*(strB 1) =..." is legal and does make sense. A variable, lets take int b = 3 for example, has a memory address and a value like this: (I made up the memory addresses)

Variable Name       Address             Value
b                   0x7ffc2ede6efc      3

Now if we create a pointer to point at that variable then that pointer will also have a memory address and a value. Here we are declaring a new pointer variable called "d" of type integer and want to set its value to the address of the variable b.

int* d = &b;

Here is what it looks like in memory.

Variable Name       Address             Value
d                   0x8fcd2aff6ec4      0x7ffc2ede6efc

Notice the value is the memory address above for the variable "b". If we go ahead and print the value of the pointer "d" it will print a memory address. if we want to actually print the value at that memory address then you first need to dereference it with "*" which will print the value of the pointer's value, if that makes sense. So why the first part is wrong is because you are adding 1 to the value of "d" before you dereference it. So you are really changing the memory address of where "d" points to, which may be something but also may be nothing. If you dereference "d" first and then add 1 you will be able to increment it but know that you are really incrementing "b". Also if you create more integer variables it does not mean that they are going to be right after one another in memory. print our their memory addresses and see for yourself!

Now in the second case you are working with an array of characters. arrays are similar to pointers.

char str[] = "hello";
char* strB = &str[0];

"str" value is the address of the first element in the array. so instead of calling the address of operator on the first element in the array you can just do:

char* strB = str;

Also this is what the string looks like in memory:

Variable Name       Address             Value
str[0]              0x7ffc2ede6ef1      'h'
str[1]              0x7ffc2ede6ef2      'e'
str[2]              0x7ffc2ede6ef3      'l'
str[3]              0x7ffc2ede6ef4      'l'
str[4]              0x7ffc2ede6ef5      'o'
str[5]              0x7ffc2ede6ef6      '\0'

The addresses of each element in the array are right next to each other which is why you can add 1 to strB and it still works. Because adding 1 will move on to the next address which in this case is the next character in the array. Another way to print it can be like this:

for (; *strB != '\0'; strB  ) printf("%c", *strB);

Every string ends with a null character so you can start at the beginning of an array and print every character by adding 1 to the address until you reach the null character.

  • Related