I had to write a program that declares char text[16]; and int number; and then fills it with input from the user. Then I have to call another function (without passing anything) and recall that data from the stack and display it.
I was able to find both of them
// This is the function that is called without passing any variables
int number;
char text[16];
cout << *(&text + 5) << endl; // This outputs the correct text but I can not figure out how to assign it to text
number = *(int*)(&number + 20); // This works and outputs the correct number and saves correctly to int number;
cout << "\tnumber: "
<< number
<< endl;
cout << "\ttext: "
<< text
<< endl;
I would like to know if there is a way to transfer the text from *(&text + 5) to char text[16];
What you are doing is going to result in undefined behavior. Depending heavily on the compiler and therefore in turn on the architecture. The proof being that when I compile and run your code with different optimization flags I get different results. Check out https://en.wikipedia.org/wiki/Buffer_overflow
The first expression *(&text + 5) evaluates to taking the address of the text pointer in memory, adding 5 to it and then dereferencing that to get a character value that is stored at that location. This can be pretty much anything on the stack at that time.
&number + 20 will definitely go off the "visible" stack, this is pointer arithmetic and will result in you adding 20*sizeof(int) to the pointer to the memory address of number on the stack.
If this is what you are intending to do then you should probably use strcpy as suggested by #JafferWilson
From reading the comments on the answer by Curious the answer is:
There is no proper way to read local variables in another function in C++ without passing them (or pointers to them or references to them) as parameters (or within objects you pass as parameters).
You can assign file scope (so called global) variables and read them in other functions. That is almost always a bad idea.
I get the feeling you might be coming from an assembler programming background to even try this sort of thing. You need to surrender a bit more to the structured programming paradigm.
Related
This is a multi part question based on a project I'm currently undertaking. I will try to make it as brief as possible while still fully explaining the question, so sorry if this is a bit long.
When it comes to std::vectors in C++, how exactly do they work with variables? For example, if I have the following code:
int myInt = 4;
std::vector<int> myIntVector;
myIntVector.push_back(myInt);
what happens? Does that area of memory inside myIntVector now have the same value of data stored inside myInt at the time of adding, but still completely separate them? Does the area of memory where myInt is stored get physically moved into a designated area inside of the memory of myIntVector?
Assuming I was correct on the last statement, why would std::cout << myInt still correctly print 4, assuming it was not changed, while std::cout << myIntVector[0] also prints out 4?
Now, for what prompted the question: the #define directive. I was experimenting with this for my project, and noticed something interesting. I used #define GET_NAME(variable) (#variable), which returns the name of the inputted variable as a character array. If I were to have the following code:
#define GET_NAME(variable) (#variable)
int myInt = 4;
std::vector<int> myIntVector;
myIntVector.push_back(myInt);
std::cout << GET_NAME(myInt) << "\n";
std::cout << GET_NAME(myIntVector[0]);
I would receive the following output:
myInt
myIntVector[0]
Why? Assuming the first statement from question 1 is correct, this is the expected output, but then we circle back to question 2. Assuming the second statement from question 2 is correct, this is the unintended output, as myInt or myIntVector[0] should be returned twice.
Thanks in advance!
When it comes to std::vectors in C++, how exactly do they work with variables?
All STL containers just copy values by default. So when you pass an int variable, it gets copied and the copy exist completely independently from the original value
why would std::cout << myInt still correctly print 4, assuming it was not changed, while std::cout << myIntVector[0] also prints out 4?
These are two different values, both equal to 4
If I were to have the following code, I would receive the following output. Why?
The macros just manipulate the text, and don't do anything fancy in your code. This statement:
std::cout << GET_NAME(myInt) << "\n";
Just turns into this under the macro:
std::cout << "myInt" << "\n";
I was writing a simple program to test how the scope of variables works, but I'm obtaining unexpected results, so I was hoping you could give me an hand to understand them.
I compiled this code
#include<iostream>
using namespace std;
void myFunction1()
{
int e;
cout << e << endl;
e++;
cout << e << endl<<endl;
}
int main()
{
cout << "MAIN" << endl;
int a,b,c,d;
cout << "a= " << a << endl;
cout << "b= " << b << endl;
cout << "c= " << c << endl;
cout << "d= " << d << endl<<endl;
cout << "MY_FUNC" << endl;
myFunction1();
myFunction1();
myFunction1();
}
and obtained this output
MAIN
a= -1617852976
b= 32767
c= 0
d= 0
MY_FUNC
32675
32676
32676
32677
32677
32678
So, there are two things I really don't understand
1) In the main() function I'm creating 4 int variables (a,b,c,d) WITHOUT initializing them, so I expect them to assume a different value each time I run the code. Strange thing is, the first variable (a) is always different, while the others always assume the same values (b=32767, c=d=0)
2) The function output is even stranger to me.
Again, I'm creating a variable e without initializing it, so the first time it assumes a random value (in the example, e=32675).....then, I increase it by one, so that it prints 32675 and 32676, and that sounds right.
But how come the second time I call the function, e keeps the previous value (32676)? I thought e was created each time I call myFunction1() and deleted at the end of the function, so that e assumed a different random value each time (since I don't initialize it). Why is the value of e stored even if the variable goes out of scope?
Uninitialized primitive values are simply not defined. They can have any value.
It is an undefined behavior. That's why it doesn't make any sense to analyze the behavior of this program.
In the main() function I'm creating 4 int variables (a,b,c,d) WITHOUT initializing them, so I expect them to assume a different value each time I run the code
This assumption is flawed. They may have a different value each time you run the code, but they may not. Anything could happen. The point of UB is that you should drop all your assumptions.
But how come the second time I call the function, e keeps the previous value (32676)? I thought e was created each time I call myFunction1() and deleted at the end of the function, so that e assumed a different random value each time (since I don't initialize it)
It does. If you replace "random" for the more correct "arbitrary", then the results you're seeing fit that pattern just fine.
It's just pure luck, and comes down to the state you're leaving unclaimed memory in at each stage of your program's execution.
A good way to help you understand this is to explain in terms of memory allocation.
When you run a program, a certain amount of memory that is not used is assigned to your variable.
Computers are lazy, the best way to delete a data is to forget where it is stored. When you assign a chunk of memory to a variable, you are telling the computer to remember where that certain data belongs to.
If it so happens that it was used prior to you assigning the memory to the variable, it will simply read (let's say 4 bytes for a common machine) and get the data from that location.
Hope that this helps =)
Again here i am because the course material for C++ was not taught very well at all. The question gives use several function definitions and calls to these functions and expects us to state the output and what exactly is going on. I have executed these functions and tried to come up with some rationale to what is happening but if someone could help me out that i would be very grateful.
function definitions (The names are all as given. I know the names are not very good):
void MyIncrementFirst(int * i) {
(*i)++;
}
void MyIncrementSecond(int i) {
i++;
}
void MyIncrementThird(int & i) {
i++;
}
void MyIncrementFourth(int ** i) {
*i = new int(0);
}
void MyIncrementFifth(int *& i) {
i = new int(69);
}
The calls to these functions have been defined as:
int * a = new int(42);
cout << "Result" << endl;
MyIncrementFirst(a);
cout << "first " << *a << endl;
MyIncrementSecond(*a);
cout << "second " <<*a << endl;
MyIncrementThird(*a);
cout << "third " <<*a << endl;
MyIncrementFourth(&a);
cout << "fourth " <<*a << endl;
MyIncrementFifth(a);
cout << "fifth " <<*a << endl;
Which produces the following:
first 43
second 43
third 44
fourth 0
fifth 69
Some of this syntax i have not seen before (e.g. *&) so i maybe completely wrong here.
First:
This seems simple enough. I am passing in a pointer to an integer, and then de-referencing the pointer and incrementing its value, so instead of incrementing the pointer i am incrementing the actual value it is pointing to. No memory allocation is used, and this function uses pass-by-reference in order to modify the value.
Second:
This is similar to the above, as the pointer is de-referenced to get the integer value from the pointer rather than the memory address. Now this function uses pass-by-value so a copy of the variable is used in the functions execution. This means that incrementing a here, will have no impact on the variable you passed in, the value of a will remain as 42, but the copy of the passed in variable will have its value changed to 43 during the functions execution.
Third:
My understanding is that the '&' operator is basically saying 'the memory address of ...' so this function will take the memory address of the passed in pointer, locate the value it points to an increment this by one. That is why 43 is printed. This is using pass-by-reference.
Fourth:
If i remember correctly the '**' syntax means a pointer to a pointer. This means that when passing &a to the function you are passing the memory address of the pointer so when you de-reference this pointer and set its value to a new int(0); you are actually overwriting the exiting data at this address (42 in this case) so the value 0 is printed. This uses pass-by-reference.
fifth:
I have not seen this syntax before (*&). I have looked up this syntax and i think it is basically saying 'pass me by reference not value' so it seems to be the same as de-referencing the pointer as mentioned earlier. Again, because this is pass-by-refence not value when the value is set to a new int(69); the current data at that location is overwritten thus 69 is outputted.
Edit: Forgot to include my question! I want to know if my thinking is correct, this is all exam prep so i want to be sure i am doing it correctly.I just want to make sure my logic is correct and if i have done anything wrong or missed anything would somebody be able to steer my in the right direction
Edit: (based on some commenter feedback)
Everything you have is mostly correct, save some confusion on your output values. However, what you have in #4 and #5 is actually not overwritten data, it's actually new data at a new address, which is assigned to the variable i. This is part of what an earlier commenter said about a potential for a memory leak. Since you're not deleting the old address before assigning a new one, that's where it could occur.
The &* syntax in the last one is a reference to a pointer. It's essentially the same as int** except you don't pass &a as the argument, it's just a
What you have there for number 5 is basically correct, but the reasoning behind it is missing the meaning of &*
You might want to clarify if you've run each of these function calls sequentially or one at a time, since your output is incorrect if you'd indeed run them sequentially as written.
For example, if loaded a text file into an std::string, did what I needed to do with it, then called clear() on it, would this release the memory that held the text? Or would I be better off just declaring it as a pointer, calling new when I need it, and deleting it when I'm done?
Calling std::string::clear() merely sets the size to zero. The capacity() won't change (nor will reserve()ing less memory than currently reserved change the capacity). If you want to reclaim the memory allocated for a string, you'll need to do something along the lines of
std::string(str).swap(str);
Copying the string str will generally only reserve a reasonable amount of memory and swapping it with str's representation will install the resulting representation into str. Obviously, if you want the string to be empty you could use
std::string().swap(str);
The only valid method to release unused memory is to use member function shrink_to_fit(). Using swap has no any sense because the Standard does not say that unused memory will be released when this operation is used.
As an example
s.clear();
s.shrink_to_fit();
I realized the OP is old but wanted to add some precision. I found this post when I was attempting to understand a behavior that seemed to contredict the answers provide here.
With gcc4.8.3, clear() might look like it's releasing memory in some scenario.
std::string local("this is a test");
std::cout << "Before clear: " << local.capacity() << '\n';
local.clear();
std::cout << "After clear: " << local.capacity() << '\n';
As expected I get
Before clear: 14
After clear: 14
Now lets add another string into the mix:
std::string local("this is a test");
std::string ref(local); // created from a ref to local
std::cout << "Before clear: " << local.capacity() << '\n';
local.clear();
std::cout << "After clear: " << local.capacity() << '\n';
This time I get:
Before clear: 14
After clear: 0
Looks like stdc++ has some optimisation to, whenever possible, share the memory holding the string content. Depending if a string is shared or not the behavior will differ. In the last example, when clear() is called, a new instance of the internal of std::string local is created and it will be empty(). The capacity will be set to 0. One might conclude from the ouput of capacity() that some memory was freed, but that is not the case.
This can be proven with the following code:
std::string local("this is a test");
std::string ref(local); // created from a ref to local
std::cout << (int*)local.data() << ' ' << (int*)ref.data() << '\n';
Will give:
0x84668cc 0x84668cc
The two strings point to the same data, i was not execting that. Add a local.clear() or anything that modifies local or ref and the adresses will then differ, obviously.
Regards
... would this release the memory that held the text?
No.
Or would I be better off just declaring it as a pointer ...
No, you'd be better off declaring the string in the scope in which it is needed, and letting its destructor be called. If you must release the memory in the scope which the string still exists, you can do this:
std::string().swap(the_string_to_clear);
I'm trying to write a simple program to show how variables can be manipulated indirectly on the stack. In the code below everything works as planned: even though the address for a is passed in, I can indirectly change the value of c. However, if I delete the last line of code (or any of the last three), then this no longer applies. Do those lines somehow force the compiler to put my 3 in variables sequentially onto the stack? My expectation was that that would always be the case.
#include <iostream>
using namespace std;
void someFunction(int* intPtr)
{
// write some code to break main's critical output
int* cptr = intPtr - 2;
*cptr = 0;
}
int main()
{
int a = 1;
int b = 2;
int c = 3;
someFunction(&a);
cout << a << endl;
cout << b << endl;
cout << "Critical value is (must be 3): " << c << endl;
cout << &a << endl;
cout << &b << endl;
cout << &c << endl; //when commented out, critical value is 3
}
Your code causes undefined behaviour. You can't pass a pointer to an int and then just subtract an arbitrary amount from it and expect it to point to something meaningful. The compiler can put a, b, and c wherever it likes in whatever order it likes. There is no guaranteed relationship of any kind between them, so you you can't assume someFunction will do anything meaningful.
The compiler can place those wherever and in whatever order it likes in the current stack frame, it may even optimize them out if not used. Just make the compiler do what you want, by using arrays, where pointer arithmetic is safe:
int main()
{
int myVars[3] = {1,2,3};
//In C++, one could use immutable (const) references for convenience,
//which should be optimized/eliminated pretty well.
//But I would never ever use them for pointer arithmetic.
int& const a = myVars[0];
int& const b = myVars[1];
int& const c = myVars[2];
}
What you do is undefined behaviour, so anything may happen. But what is probably going on, is that when you don't take the adress of c by commenting out cout << &c << endl;, the compiler may optimize avay the variable c. It then substitutes cout << c with cout << 3.
As many have answered, your code is wrong since triggering undefined behavior, see also this answer to a similar question.
In your original code the optimizing compiler could place a, b and c in registers, overlap their stack location, etc....
There are however legitimate reasons for wanting to know what are the location of local variables on the stack (precise garbage collection, introspection and reflection, ...).
The correct way would then to pack these variables in a struct (or a class) and to have some way to access that structure (for example, linking them in a list, etc.)
So your code might start with
void fun (void)
{
struct {
int a;
int b;
int c;
} _frame;
#define a _frame.a
#define b _frame.b
#define c _frame.c
do_something_with(&_frame); // e.g. link it
You could also use array members (perhaps even flexible or zero-length arrays for housekeeping routines), and #define a _frame.v[0] etc...
Actually, a good optimizing compiler could optimize that nearly as well as your original code.
Probably, the type of the _frame might be outside of the fun function, and you'll generate housekeeping functions for inspecting, or garbage collecting, that _frame.
Don't forget to unlink the frame at end of the routine. Making the frame an object with a proper constructor and destructor definitely helps. The constructor would link the frame and the destructor would unlink it.
For two examples where such techniques are used (both because a precise garbage collector is needed), see my qish garbage collector and the (generated C++) code of MELT (a domain specific language to extend GCC). See also the (generated) C code of Chicken Scheme or Ocaml runtime conventions (and its <caml/memory.h> header).
In practice, such an approach is much more welcome for generated C or C++ code (precisely because you will also generate the housekeeping code). If writing them manually, consider at least fancy macros (and templates) to help you. See e.g. gcc/melt-runtime.h
I actually believe that this is a deficiency in C. There should be some language features (and compiler implementations) to introspect the stack and to (portably) backtrace on it.