Why integer pointers use the same memory address

Debojit Acharjee 455 Reputation points
2023-05-29T04:53:36.2833333+00:00

Every time I run this program, I see that the address of the integer pointers are always the same. Why is that?

#include <stdio.h>

int main()

{

    int *a;

    char *b;

    

    *a = 10;

    printf("The memory location of 10 is: %x\n", a);

    

    *a = 20;

    

    printf("The memory location of 20 is: %x\n", a);

    b = "C";

    printf("The memory location of \"C\" is: %x\n", b);

    b = "Programming";

    printf("The memory location of \"Programming\" is: %x\n", b);

    return 0;

}

Output:

The memory location of 10 is: 2a8000

The memory location of 20 is: 2a8000

The memory location of "C" is: 4050aa

The memory location of "Programming" is: 4050cf

Developer technologies | C++
Developer technologies | C#
{count} votes

5 answers

Sort by: Most helpful
  1. RLWA32 49,536 Reputation points
    2023-06-06T09:38:25.0766667+00:00

    Hopefully the following will clarify for the Questioner how the stack based variables (int a and char b[1]) appear in memory, why the same addresses are printed and the effect of the buffer overflow from the coding error contained in the code here:

    #include <stdio.h>
    
    int main()
    
    {
        int a;
        char b[1];
    
        a = 0;
        printf("The memory location of 0 is: %x\n", &a);
    
        a = 100;
        printf("The memory location of 100 is: %x\n", &a);
    
        b[1] = 'c';
        printf("The memory location of 'c' is: %x\n", &b[1]);
    
        b[1] = 'd';
        printf("The memory location of \"C\" is: %x\n", &b[1]);
    
        return 0;
    }
    

    Uninitialized variables before assigning 0 to a -

    watch_uninitialized

    memory_uninitialized

    The first byte highlighted is the 1 byte array b and the second 4 bytes highlighted are the int variable a. Note that the addresses in the watch window agree with the addresses in the memory window.

    Now, assign 0 to a -

    watch_A0

    memory_A0

    Note that the changes from the assignment are displayed in red.

    Assign 100 to a -

    watch_A100

    memory_A100

    Now for the incorrect code that writes to a memory address b[1] that is outside the bounds of the char array. Assign 'c' to b[1] -

    watch_b1c

    memory_b1c

    Results of coding error should be evident. The 1 byte char array b is untouched. However, writing outside the bounds of the b array changed the value of the int a variable. Addresses &a and &b[1] point to the same location in memory. The same thing happens when the next statement assigns 'd' to b[1] -

    watch_b1d

    memory_b1d

    The above results and reproduction of the Questioner's "same address" issue was produced with an x86 debug build with runtime checks disabled.

    1 person found this answer helpful.
    0 comments No comments

  2. David Lowndes 4,726 Reputation points
    2023-05-29T08:51:41.0966667+00:00

    Your code as shown is littered with errors & warnings. How have you got it to compile and not notice them?
    For example, you should be seeing something like the following if you're using Visual Studio:
    Error C4700 uninitialized local variable 'a' used

    You've never set the pointers, so they're random, but in a debug build will probably be some default value. It's a feat that you've somehow managed to get what you have to run at all.

    0 comments No comments

  3. Anonymous
    2023-05-29T09:10:42.4566667+00:00

    Hi @Debojit Acharjee , Welcome to Microsoft Q&A.

    A pointer of class int has an address assigned when it is declared.

    You just modified the value on the address, and did not modify the address itself so it will not change.

    It was as if there was just another person in the house, and it was still the same house.

    For char pointers.

    And actually using different compilers, this may change.

    For correct use, you should manually assign memory space.

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h> 
    #include<string>
    int main()
    {
    	int* a;
    	char* b;
    
    	a = (int*)malloc(sizeof(int));
    	if (a == NULL) {
    		printf("Failed to allocate memory for a\n");
    		return 1;
    	}
    
    	*a = 10;
    	printf("The memory location of 10 is: %p\n", (void*)a);
    
    	*a = 20;
    	printf("The memory location of 20 is: %p\n", (void*)a);
    
    	b = (char*)malloc(sizeof(char) * 10);
    	if (b == NULL) {
    		printf("Failed to allocate memory for b\n");
    		free(a); 
    		return 1;
    	}
    
    	strcpy(b, "C");
    	printf("The memory location of \"C\" is: %p\n", (void*)b);
    
    	strcpy(b, "Programming");
    	printf("The memory location of \"Programming\" is: %p\n", (void*)b);
    
    	free(a);
    	free(b);
    
    	return 0;
    }
    
    
    

    User's image

    Best Regards,

    Jiale


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment". 

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

  4. Dr. Volker Milbrandt 80 Reputation points
    2023-05-29T09:12:13.3633333+00:00
    • You don't change the pointer a, you only change the value *a of the address the pointer a is pointing to. See the linked article Constant pointers vs. pointer to constants in C and C++ in your other question https://learn.microsoft.com/en-us/answers/questions/1292559/why-this-loop-runs-only-once.
    • Above you assign to the pointer b (no asterisk) the address of the char arrays "C" and "Programming".
    • You assign to the memory *a (with asterisk) where the pointer a is pointing to the values 10 and 20.
    • To print the address you should use %p and not an integer value with %x.
    • But what is even worse: you don't allocate memory for the int *a, thus you overwrite a random memory location! Please either allocate memory with new/delete or use an unique_pointer.

    Now a fixed example fof your code:

    #include <stdio.h>
    
    int main()
    {
    	int* a = new int; // allocate memory for the int
    	const char* b; // const
    
    	*a = 10;
    	printf("The memory location of 10 is: %p\n", a); // print pointer address, not int 
    
    	*a = 20;
    	printf("The memory location of 20 is: %p\n", a);
    
    	b = "C";
    	printf("The memory location of \"C\" is: %p\n", b);
    
    	b = "Programming";
    	printf("The memory location of \"Programming\" is: %p\n", b);
    
    	delete a; // free the allocated memory (avoid memory leeks)
    
    	return 0;
    }
    

    Or with garbage collection:

    #include <stdio.h>
    #include <memory>
    
    int main()
    {
    	std::unique_ptr<int> a = std::make_unique<int>(); // allocate a pointer with garbage collection, no delete required
    	const char* b;
    
    	*a = 10;
    	printf("The memory location of 10 is: %p\n", &a);
    
    	*a = 20;
    	printf("The memory location of 20 is: %p\n", &a);
    
    	b = "C";
    	printf("The memory location of \"C\" is: %p\n", b);
    
    	b = "Programming";
    	printf("The memory location of \"Programming\" is: %p\n", b);
    
    	return 0;
    }
    

  5. Bruce (SqlWork.com) 77,686 Reputation points Volunteer Moderator
    2023-06-05T16:30:41.2633333+00:00

    in C, a variable is an address. the address is either a static memory location, a stack memory location or heap memory location.

    if you access a variable directly, you are accessing the value stored in this address. C has operators to use the address as a pointer, or to get a variables address instead of value.

    you must be using a pretty weak C compiler, because your samples often use uninitialized pointers.

    #include <stdio.h>
    
    int main(int argc, const char * argv[]) {
        // define variables on stack - 64 bit int on my machine
        int a = 0;      // a address contains 0
        int b = 1;      // b address contains 1
        int *pa  = &a;  // pa address contains address of variable a
        int *pb = &b;   // pb address contains address of variable b
        //int *pl = &1  // illegal, can not assign address of literal.
        
        // print address (notice each is - 4 bytes from each other due to being stack addresses)
        printf("addresses: a:%i b:%i pa:%i pb:%i\n", &a, &b, &pa, &pb);
        // addresses: a:1876947532 b:1876947528 pa:1876947520 pb:1876947512
        
        // print values (notice pa & pb are the address of a & b)
        printf("values: a:%i b:%i pa:%i pb:%i\n", a, b, pa, pb);
        // values: a:0 b:1 pa:1876947532 pb:1876947528
        
        // now update values via pointers
        *pa = 10;
        *pb = 20;
    
        // print values (notice a & b changed, but pa & pb are still the addresses of a & b)
        printf("values: a:%i b:%i pa:%i pb:%i\n", a, b, pa, pb);
        // values: a:10 b:20 pa:1876947532 pb:1876947528
    
        // make pb point to same address as pa
        pb = pa;
    
        printf("values: a:%i b:%i pa:%i pb:%i\n", a, b, pa, pb);
        // values: a:10 b:20 pa:1876947532 pb:1876947532
        
        return 0;
    }
    
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.