Stack Memory Adress Differences - c++

i am new in c++.
I do have 2 code snippets.
FIRST
#include <iostream>
int main()
{
int firstInteger = 1;
std::cout << "First memory adress: " << &firstInteger << std::endl;
int secondInteger = 2;
std::cout << "Second memory adress: " << &secondInteger << std::endl;
return 0;
}
Result is
First memory adress: 00000039A2F7F934
Second memory adress: 00000039A2F7F954
Second integer has a bigger hex value.
SECOND
#include <iostream>
void someFunction() {
int secondInteger = 2;
std::cout << "Second memory adress: " << &secondInteger << std::endl;
}
int main()
{
int firstInteger = 1;
std::cout << "First memory adress: " << &firstInteger << std::endl;
someFunction();
return 0;
}
Result is
First memory adress: 00000093953EF744
Second memory adress: 00000093953EF624
First one is bigger this time.
Can somebody explain what is the difference between them.
Thank you.

There is no guarantee of any ordering or distance between addresses of different variables (or complete objects in general), except that the storage of the objects will not overlap while they are in their lifetime. The compiler is allowed to layout the stack however it considers reasonable and efficient. It is wrong to assume any ordering must be present.
For example on GCC 12.2 x64 without optimization flags enabled I get a smaller address for the second variable in both cases here, but your behavior with -O2 optimizations enabled here.

Related

What is the relationship between an array and its address?

The following code:
#include<iostream>
int main (void) {
int lista[5] = {0,1,2,3,4};
std::cout << lista << std::endl;
std::cout << &lista << std::endl;
std::cout << lista+1 << std::endl;
std::cout << &lista+1 << std::endl;
std::cout << lista+2 << std::endl;
std::cout << &lista+2 << std::endl;
std::cout << lista+3 << std::endl;
std::cout << &lista+3 << std::endl;
return (0);
}
Outputs:
0x22ff20
0x22ff20
0x22ff24
0x22ff34
0x22ff28
0x22ff48
0x22ff2c
0x22ff5c
I understood that an array is another form to express a pointer, but we cannot change its address to point anywhere else after declaration. I also understood that an array has its value as the first position in memory. Therefore, 0x22ff20 in this example is the location of the array's starting position and the first variable is stored there.
What I did not understand is: why the other variables are not stored in sequence with the array address? I mean, why lista+1 is different from &lista+1. Should not they be the same?
In pointer arithmetic, types matter.
It's true that the value is the same for both lista and &lista, their types are different: lista (in the expression used in cout call) has type int* whereas &lista has type int (*)[5].
So when you add 1 to lista, it points to the "next" int. But &lista + 1 points to the location after 5 int's (which may not be a valid).
Answering the question as asked:
std::cout << &lista+1 << std::endl;
In this code you take the address of array lista and add 1 to obtained answer. Given the sizeof of the array is sizeof(int) * 5, which means when you increment a pointer to it by 1 you add sizeof(int) * 5 to the pointer address, you end up with a number you see.

using int pointer in multiple couts

I'm quite new to the world of pointers in C/C++ so this may be quite an easy question for you:
The following C++-Code works normally
#include <iostream>
int main()
{
int theInt = 1337;
int & theReference = theInt;
int * thePointer = &theInt;
std::cout << "int: " << theInt << "\n";
std::cout << "referenz: " << theReference << "\n";
std::cout << "pointer: " << *thePointer << "\n";
std::cout << "pointer: " << *thePointer << "\n";
//std::cout << "foo" << "\n";
return 0;
}
but stops working when changing
//std::cout << "foo" << "\n";
to
std::cout << "foo" << "\n";
.
By "stops working" I mean: "is blocked by my norton security as a potential threat" (resulting in a return code of "0x76F531AF" if this is any help). Since norton normally doesn't interfere withe my programming I assume the double use of the int pointer in cout somehow results in a segfault...
Thx for your help!
PS:
I use Code::Blocks on Windows 8.1 with the GCC compiler and GDB debugger from TDM-GCC (version 4.7.1, 32 bit).
EDIT: removed deletion of pointer -> problem remains.
You can only delete objects created on the heap (using new or C-style malloc and such).
// allocate on the heap
int *intOnTheHeap = new int;
// do some stuff with it
*intOnTheHeap = 0;
(*intOnTheHeap)++;
std::cout << *intOnTheHeap << std::endl;
// deallocate
delete intOnTheHeap;
If you take a pointer to a local variable, it will point to an entry on the stack. You don't need to and shouldn't deallocate that memory yourself. The memory is "freed" by changing the stackpointer automatically when your variable runs out of scope (at the end of the function).
void myFunction() {
int localVariable;
int *pointerToLocalVariable = &localVariable;
// forbidden and unnecessary:
//delete pointerToLocalVariable;
// here (end of the block) the memory on the stack
// will be freed automatically
}
Since I got the same error after Norton-Interception in totally different contexts, this seems to be a case of Code::Blocks Norton incompatibility.

Size of data types using pointers?

I want to see the size of data types on my computer. So I started with int datatype with this code :
#include <iostream>
using namespace std;
int main()
{
int t, *tpntr1, *tpntr2;
tpntr1 = &t;
cout << "The first address: \t" << tpntr1;
tpntr2 = ++tpntr1;
cout << "\n The second address : \t" << tpntr2;
unsigned int size= (tpntr2 - tpntr1);
cout << "\n the size of int : \t" << size<<"\n";
return 0;
}
After compiling in visual studio the size is returned to be 0. In a particular run the first address was 0028FBA4 and second was 0028FBA8 but the difference is coming out as zero. Can some one please point out what am I doing wrong here ? I guess its something related to hexadecimal to decimal conversion.
Here's a hint: Move the couts to the end to see what's going on:
#include <iostream>
using namespace std;
int main()
{
int t, *tpntr1, *tpntr2;
tpntr1 = &t;
tpntr2 = ++tpntr1;
unsigned int size= (tpntr2 - tpntr1);
cout << "The first address: \t" << tpntr1;
cout << "\n The second address : \t" << tpntr2;
cout << "\n the size of int : \t" << size<<"\n";
return 0;
}
The addresses are the same. You're literally assigning tpntr2 to tpntr1.
If you change tpntr2 = ++tpntr1 to
tpntr2 = tpntr1;
tpntr2++;
It will partially do what you want. Note that this will print 1 as the size. I may be mistaken, but pointer arithmetic takes into consideration the size of the type (someone please correct me if this isn't the case. I can't explain it otherwise).
As Carcigenicate pointed out, your main issue is that ++ modifies the value. However, you might also not get the result you want due to how pointer arithmetic works.
A corrected form of this would read:
tpntr1 = &t;
tpntr2 = tpntr1;
tpntr2++;
However, your result will be 1, because tpntr2 - tpntr1 will return the difference in terms of the number of ints. Since an int is 4 bytes (at least, in my implementation), this will print that the difference is 1, even though the memory addresses are 4 apart.
If you want the actual bytes (which would be 4), you need to cast to a type which will bypass this behavior. You have two options: cast the pointers to an int, which would make it a simple math operation on numbers, or reinterpret_cast<char*>, which will tell it to treat the pointers as being to one byte of memory. For example, this will show the size as 4:
int main()
{
int t, *tpntr1, *tpntr2;
tpntr1 = &t;
tpntr2 = tpntr1;
tpntr2++;
unsigned int size= (reinterpret_cast<char*>(tpntr2) - reinterpret_cast<char*>(tpntr1));
cout << "The first address: \t" << tpntr1;
cout << "\n The second address : \t" << tpntr2;
cout << "\n the size of int : \t" << size<<"\n";
return 0;
}

Converting char* to int after using strdup()

Why after using strdup(value) (int)value returns you different output than before?
How to get the same output?
My short example went bad, please use the long one:
Here the full code for tests:
#include <stdio.h>
#include <iostream>
int main()
{
//The First Part
char *c = "ARD-642564";
char *ca = "ARD-642564";
std::cout << c << std::endl;
std::cout << ca << std::endl;
//c and ca are equal
std::cout << (int)c << std::endl;
std::cout << (int)ca << std::endl;
//The Second Part
c = strdup("ARD-642564");
ca = strdup("ARD-642564");
std::cout << c << std::endl;
std::cout << ca << std::endl;
//c and ca are NOT equal Why?
std::cout << (int)c << std::endl;
std::cout << (int)ca << std::endl;
int x;
std::cin >> x;
}
Because an array decays to a pointer in your case, you are printing a pointer (ie, on non-exotic computers, a memory address). There is no guarantee that a pointer fits in an int.
In the first part of your code, c and ca don't have to be equal. Your compiler performs a sort of memory optimization (see here for a full answer).
In the second part, strdup allocates dynamically a string twice, such that the returned pointers are not equal. The compiler does not optimize these calls because he does not seem to control the definition of strdup.
In both cases, c and ca may not be equal.
"The strdup() function shall return a pointer to a new string, which is a duplicate of the string pointed to by s1." source
So it's quite understandable that the pointers differ.

"UnConsting" const value via pointer

First, sorry for possible question redundancy.
Doing some little experiments with C/C++ pointers in GCC I encountered this somewhat weird behaviour when bypassing constantness of value at the pointer address.
#include <iostream>
int main()
{
using namespace std;
const double number = 100;
//bypassing constantess of pointed-to value
double * pointer_to_value = (double *) &number;
*pointer_to_value += 200;
cout << "Adress of number: " << &number << "\tValue of number: " << number << endl <<
" Pointer value: " << pointer_to_value << "\tDereferencing pointer: " << *pointer_to_value;
return 0;
}
I would expect both form of checking the value yielding same results. Location of value is same in both cases. Program generates following output, however:
Adress of number: 0x22ff30 Value of number: 100
Pointer value: 0x22ff30 Dereferencing pointer: 300
Anyone capable of explaining?
Thanks in advance.
It's undefined behaivor.
It's irrelevant why exactly it happens (actually because the compiler inlines the value).
"UnConsting” const value via pointer is a Undefined Behavior.
So it is not posible to define a behavior not defined by the Standard.
Compiler optimization. Compiler doesn't expect you to try and trick it like that, it knows that the value is const, so it just cached it. Try to compile it without any optimization, and see if it makes any difference.
Generally the meaning of const is:
constant - the object shall not be modified. Attempt to do so results in undefined behavior. On most of the compilers it is compile-time error.
Compiler optimization. You can overcome that by adding volatile keyword to the variable.
#include <iostream>
int main()
{
using namespace std;
volatile const double number = 100;
//bypassing constantess of pointed-to value
double * pointer_to_value = (double *) &number;
*pointer_to_value += 200;
cout << "Adress of number: " << &number << "\tValue of number: " << number << endl <<
" Pointer value: " << pointer_to_value << "\tDereferencing pointer: " << *pointer_to_value;
return 0;
}
My guess is that gcc has done some optimizations on your behalf, replacing the reference to << number with << 100. Should be possible to verify by looking at the generated asm code.