Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Memory Address

Tags:

c++

memory

Please excuse me if this is a repeated question

This is my code

#include "stdafx.h"
#include <stdio.h>
#include "iostream"
#include <stdlib.h>
using namespace std;

int main()
{
    char * name = "Hello";

    cout << "2" << endl;
    cout << "Address2 is " << &name <<  "   value at address is " << * (&name) << endl;
    cout << "Next address2 is " << &name + 1 << "   value at address is " << name + 1 << "  " << sizeof(char) << endl;

    cout << "3" << endl;
    cout << "Address3 is " << &name << "   value at address is " << name << endl;

    cout << "Next address3 is " << &name + sizeof name << "   value at address is " << name + sizeof name << endl;
    getchar();
}

and this is the output

  1. Address2 is 003EFAA4 value at address is Hello // easy for me to understand

  2. Next Address2 is 003EFAA8 (This is where i struggle to understand. My understanding is the next address should be 003EFAA5 considering char is of 1 Byte?

  3. output same as 1

  4. Next Address2 is 003EFAB4 (This is where i struggle to understand too. My understanding is the next address should be 003EFAA8 when address of variable name is 003EFAA4 considering size of char pointer is of 4 Byte?

My understanding about memory is the addresses are referenced in terms of bytes. If that is true then why in number 3 above it gives me the address which is 4 bytes further and in number 4 above it gives me the next address that is 10 bytes further?

Any explanation would be highly appreciated. Thank you

like image 274
Faisal Khan Avatar asked Jun 27 '19 12:06

Faisal Khan


Video Answer


4 Answers

Next Address2 is 003EFAA8 (This is where i struggle to understand. My understanding is the next address should be 003EFAA5 considering char is of 1 Byte?

When you do &name + 1 you go to the next address of the type of name. name is not a char though. It is a char* and on your system a char* has a size of 4. This is why it goes 4 bytes forward, as that is where the next char* could be located.

Next Address2 is 003EFAB4 (This is where i struggle to understand too. My understanding is the next address should be 003EFAA8 when address of variable name is 003EFAA4 considering size of char pointer is of 4 Byte?

This is basically the same thing that is happening above, but instead of going to the next char*, you are going to the sizeof name next element which in this case is the fourth element.

like image 65
NathanOliver Avatar answered Sep 27 '22 18:09

NathanOliver


&name is of type char**. The way pointer arithmetic works, if you add to it, it increases that much times the size of char* (because a char** points to a char*, and this way it would point to the next char* if there were an array of char*). It looks like the size of char* is 4 on your system. So if &name is 003EFAA4, then &name + 1is 003EFAA8 (that's 4 more).

sizeof name is 4, so if you add that to &name it increases by 16. Hence whey you get 003EFAB4, that's 0x10 (or 16) more than 003EFAA4.

like image 42
Blaze Avatar answered Sep 27 '22 18:09

Blaze


Welcome to pointer arithmetics.

char *name = "hello";

name is a pointer to character. It stores the address of "hello" string literal, ie. the address of character h (the address of an array is equal (to the value) to the address of the first element of an array). You should note that string literals are immutable, you can't modify them. So it's best to change the type to const char*.

&name

This is a pointer to the variable name. Not a pointer to "hello" string literal, but a pointer to a pointer. The 003EFAA4 is the address of name variable. The variable was allocated by the compiler on stack inside the main() function.

*(&name)

The *& rule (here) themselves out. So *&name is equal to name. This prints the value of the name pointer, ie. this is the pointer to "hello" string literal, ie. this is the pointer to the character h inside "hello" string literal. Not &name. Address of h character.

&name + 1

The &name has the char ** type, ie. it as a pointer to a pointer to a character. From pointer arithmetics, the &name + 1 is equal to the value to (uintptr_t)&name + 1 * sizeof(*&name). sizeof(*&name) is sizeof(name) it is sizeof(char*), so it's (uintptr_t)&name + sizeof(char*). On your architecture sizeof(char*) is 4 bytes (32 bit system?), so the pointer is incremented by 4. Ie. 003EFAA4 + 4 = 003EFAA8.

name + 1

The name has the type of char*. From pointer arithmetics name + 1 is equal to (uintptr_t)name + sizeof(*name). sizeof(*name) is sizeof(char). sizeof(char) is defined to be equal 1. This prints the address of e char inside "hello" string literal.

&name + sizeof name

&name has the type of char**, so the value of &name is incremented sizeof(name) * sizeof(char*) times. Assizeof(name)is equal tosizeof(char*), this issizeof(char*) * sizeof(char*)ie.4*4 = 16` on your computer.

name + sizeof name

This increments the pointer name value by value of sizoef(name) * sizeof(char). sizeof(name) is sizeof(char*) is 4 on your architecture, sizeof(char) is 1. So name + sizeof name is the address of character o inside "hello" string literal, ie. 003EFAA8.

@edit rewritten some parts

like image 37
KamilCuk Avatar answered Sep 27 '22 18:09

KamilCuk


You've got one too many levels of indirection here.

&name is a char**, i.e. a pointer to a character pointer. This means that if you +1 then you add the size of a pointer, not the size of a character. name is already a char*.

The problem then is doing pointer arithmetic on name and then printing the pointer address using cout rather than the string at the new char*. You can do this by casting to void*, e.g.

cout << "Next address2 is " << (void*)(name + 1)

using C-style casts.

like image 26
Rup Avatar answered Sep 27 '22 19:09

Rup