Keeping track of objects and references [closed] - c++

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
If we comment out the emphasized line below we get 777 in the console.
Otherwise we get some garbage like (-534532345).
My environment is Microsoft Visual Studio 2012 Pro.
class C
{
public:
C () { x = 777; }
void ou() {cout << x;}
protected:
int x;
};
class A
{
public:
A(C & rrc) : rc(rrc) {};
void koo () {rc.ou();}
protected:
C & rc;
};
int _tmain(int argc, _TCHAR* argv[])
{
C c;
C * pc = new C;
A a(*pc);
delete pc; // <<<< this line
a.koo();
return 0;
}
Can anyone help me figure out why I am seeing this behavior?

At the point you call a.koo(), you've deleted the underlying object that its rc reference refers to. That's of course UB. What happens next is likely to have consistent behavior on a given platform for a given compilation, and may even output 777 (actually, will likely output 777 since the underlying object was very recently deleted). In your case, it seems that either the memory that had been previously allocated to _tmain()'s pc object has been reallocated to something else that has overwritten it, or else you're using a debug build whose memory allocator explicitly overwrites deleted/freed memory with some fixed value, typically nonzero and not all ones, but something that's otherwise recognizable like 0xAAAAAAAA or 0xDEADDEAD. Since -534532345 is 0xE023AF07 (or 0xFFFFFFFFE023AF07), I'm guessing it's the former (the memory has been allocated to something else which has overwritten it). Since the call to a.koo() in your example immediately follows delete pc, I find it surprising that it's already been overwritten so soon, but technically anything's possible since it's UB.

The delete leaves you with a dangling reference, which you follow, leading to undefined behaviour. It is not a hole in C++ or MS VS. The language allows for many illegal actions to go unchecked, and leave it up to the programmer not to invoke UB.

The code has Undefined Behavior. You are holding the reference of an object which no longer exists. So, rc.ou() behavior is undefined.

If you delete pc, then A::rc will point to garbage location and rc.ou(); will output garbage as well. This is expected behavior and it will do this regardless of the compiler you are using
Btw 99[.99]% of the time you think you've found a bug in a compiler, it really is your bug

Related

Returning a struct by value vs by reference [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I want to return multiple values in C++ and I have this snippet of code:
struct returns
{
int row_locs, col_locs;
int row_descriptors, col_descriptors;
double **locs;
double **descriptors;
};
void returns (int &row_locs, int &col_locs, int &row_descriptors, int &col_descriptors, double **locs, double **descriptors)
{
//make some changes in variables
}
The question is "What consumes more time : struct or call by reference?"
The difference is negligible in both cases. You shouldn't worry about these issues until you found them to be really issues. Short answer: do the way you like more and consider different aspects like how you will use the returned values later.
If you pass arguments by reference then they're already allocated on stack or dynamically and their pointed values are filled by the function. Time is spent in copying all the pointers to the stack and in storing at their addresses in called function.
In the second case the whole struct is allocated on stack and filled (probably by a single constructor that is missing in your struct). Time is spent in constructing the object onto the stack and in filling its values.
When function returns something bigger than long (on x86 and other 32 bit processors) or long long (on x86_64 and another 64 bit architectures) it returns pointer to alocated memory and then data is being copied to local structure.
struct example
{
long long a,b,c;
};
example create_new_struct(void)
{
example tmp; //new object is created
tmp.a = 3;
tmp.b = 4;
bmp.c = 5;
return example; //in low-level pointer is returned and all data copied
}
void modify_existing_structure(example & tmp)
{
tmp.a = 3; //setting data directly
tmp.b = 4;
tmp.c = 5;
return;
}
int main(void)
{
example a = create_new_struct(), b; //varaibles are being copied
modify_existing_structure(b); //variables are being set directly
return 0;
}
So you definitly shoud use references. But (as was noticed) your code makes zero sense. You shoud not use anonymous structures and parse all variables separated. In your code you create six pointers instead of one for each function call.
Also, I think you shoud learn more about object-oriented programming.

std::string optimization? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Someone want to explain me which code is faster ? and what is the best way to optimise a string assignment ?
code 1 :
std::string result;
int main()
{
for(int i=0;i<1000;i++)
{
/*some code*/
result = stringVar;
/* some code using result */
}
}
code 2 :
int main()
{
for(int i=0;i<1000;i++)
{
/*some code*/
std::string result = stringVar;
/* some code using result */
}
}
And to assigne value :
std::string var;
var.assign("value");
//or
var="value";
And it's possible to release memory used by the value before to add a new one ?
Thank if you can help me to understand that :)
In the case of:
for (...)
std::string result = blah;
the compiler must construct and destruct result each time through the for loop, probably requiring heap allocation and deallocation calls.
In the case of:
std::string result;
for (...)
result = blah;
the string implementation might be able to optimize some heap allocation and deallocation away by only reallocation when blah is to big to fit in result's current buffer.
var=x and var.assign(x) should result in the same code; I would not expect a substantial difference either way.
The first is probably somewhat faster, because it can re-use the allocated memory from the previous pass; the second one destroys the string at the end of each pass through the loop, so frees the storage for the content of the string. An optimizer that keeps the object around, despite it being defined in the loop body, is violating the language rules.
In Code 1, operator= will be called, this is usually implemented by creating a temp object (using copy constructor) and then swapping the guts of the temp object with the lhs object. So a copy constructor, a swap, and a delete of the temp object (when the method operator=() exits) is done in code 1.
In Code 2, a copy constructor is called, and finally the object will be deleted when the for loop pass ends.
So Code 1 has the extra step of swapping the guts of the string class. Although the implementation of operator= might be not as described above for some string libs and so the best advise is to test it for your environment.

c++ delete pointer issue, can still access data [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
I don't really understand why are those pointer accessible ... any help appreciated
#include <iostream>
class Wicked{
public:
Wicked() {};
virtual ~Wicked() {};
int a;
int b;
};
class Test
{
public:
Test() {};
virtual ~Test() {};
int c;
Wicked * TestFunc()
{
Wicked * z;
c = 9;
z = new Wicked;
z->a = 1;
z->b = 5;
return z;
};
};
int main()
{
Wicked *z;
Test *t = new Test();
z = t->TestFunc();
delete z;
delete t;
// why can I set 'z' when pointer is already destroyed?
z->a = 10;
// why does z->a print 10?
std::cout << z->a << std::endl;
// why does t->c exist and print correct value?
std::cout << t->c << std::endl;
//------------------------------------------------------
int * p = new int;
*p = 4;
// this prints '4' as expected
std::cout << *p << std::endl;
delete p;
// this prints memory address as expected
std::cout << *p << std::endl;
return 0;
}
Deleting a pointer doesn't zero out any memory because to do so would take CPU cycles and that's not what C++ is about. What you have there is a dangling pointer, and potentially a subtle error. Code like this can sometimes work for years only to crash at some point in the future when some minor change is made somewhere else in the program.
This is a good reason why you should NULL out pointers when you've deleted the memory they point to, that way you'll get an immediate error if you try to dereference the pointer. It's also sometimes a good idea to clear the memory pointed to using a function like memset(). This is particularly true if the memory pointed to contains something confidential (e.g. a plaintext password) which you don't want other, possibly user facing, parts of your program from having access to.
That's undefined behaviour. Anything can happen.You were lucky this time. Or perhaps unlucky since it would be preferable to get a runtime error! Next time round maybe you'll get a runtime error.
It's not really very useful to reason about why you see a particular manifestation of undefined behaviour. It's best to stick to the well-defined behaviour about which you can reason.
C++ won't stop you from writing to an arbitrary location in memory. When you allocate memory with new or malloc, C++ finds some unused space in memory, marks it as allocated (so that it doesn't accidentally get handed out again), and gives you its address.
Once you delete that memory however, C++ marks it as free and may hand it out to anyone that asks for it. You can still write to it and read from it, but at this point, someone else might be using it. When you write to that place in memory, you may be overwriting some value you have allocated elsewhere.
Here
// why can I set 'z' when pointer is already destroyed?
z->a = 10;
z still points at a memory location.
But it no longer blongs to you. You have passed it to delete and said take care of this pointer. What it does is no longer your concern. Its like when you sell your car; it still exists but its not yours so opening the door and looking in may be possible, but it may result in the police arresting you.
Same with deleted pointers the memory exists but does not belong to you.
If you look inside it may work, but it may also cause a segmentation fault as the library has flushed the page (you never know).
delete z; just deallocates the memory z was pointing to, it does not destroy the pointer itself.
So z becomes a wild pointer.
Because deleting a block of memory does not zero the value of all pointers that point to it. Deleting memory merely makes a note that the memory is available to be allocated for some other purpose. Until that happens, the memory may appear to be intact -- but you can't count on it, and on some compiler/runtime/architecture combinations, your program will behave differently -- it may even crash.

Beginner's question: Why can't I access an object's members when it is in a vector? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
This is probably a basic question.
I have a vector of a data type 'player' that I have defined myself using a struct:
struct player {
string player_name;
string label;
...
...
}
I then having a function taking a vector of these player data types as a parameter and I want to access the members in the struct i.e.
void foo(vector<player> players) {
cout << players.at(0).player_name;
}
The at(i) works because it is a function of vector. However, I can't access player_name. Why is this and how can I solve it? Apologies if this is basic and boring.
Following code accesses player in vector:
#include <string>
#include <vector>
using namespace std;
struct player {
string player_name;
string label;
};
int main() {
vector <player> p;
p.push_back( player() );
p.at(0).player_name = "fred";
}
Your problem is that foo() returns but you don't see the side-effect of the changed player_name, I guess?
It's because you've passed the vector to foo() by value rather than reference. foo() is operating on a copy of the vector rather than whatever original you passed to it, so the player_name change is lost when the function ends.
Try changing the function signature to void foo(vector<player>& players).
(Note that I've added an ampersand to make the parameter a reference.)
You should not get a compilation error since the code you posted is fine. If you are getting a runtime-error make sure you have inserted at least one object into the vector before you try to access it.
just speculation
if you get a compile error:
probably you declare a class instead of a struct.
if you get a runtime error:
the vector is empty
no error but not result:
you haven't flush the stream. Add std::endl or call std::cout.flush()

Find address of variables in main? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 13 years ago.
Recently while surfing some C++ blogs, I came across a small C teaser program in one of them.
#include<stdio.h>
int find_addr()
{
/*fill your code here*/
}
int main()
{
int i,j;
clrscr();
find_addr();
return 0;
}
The question is to find the address of variables i & j without touching the main function. I haven't been able to figure it out yet. Feels awful that I couldn't even solve this minor question :((.
EDIT:
The above program had lot of non-standard statements like the use of inclusion of conio.h anbd other non standard headers and its functions , getch() and other statements, I edited it in a hurry and forgot to omit void from void main(), apologies for that.
EDIT2: I have given my one vote to close this thread since I perceive through the responses posted here that there are non-standard issues related to the question.
I think I found where you read the puzzles. Most of the programs use typeless main(), or worse, void main(). They assume a lot of system- and/or compiler-specific things. The programs on the page are not very good quality, and make for a bad tutorial. Please stay away from it.
For example, this is the first program:
what is the output? Definitely the output is not what you think! so think more..
main()
{
int i = 300;
char *ptr = &i;
*++ptr = 2;
printf("%d",i);
getch();
}
Third program:
what is the output of the following code if array name starts with 65486?
void main()
{
int num[] = {10,11,12,13};
printf("%u %u",num,&num);
}
I could go on, but there is no need really. As I said, stay away from this page!
I think it could look like the following, but it is not conformant way and you shouldn't use it in practice.
int find_addr()
{
int t;
int* i_addr = &t - <some platform&compiler&whatever specific constant>;
int* j_addr = &t - <some platform&compiler&whatever specific constant>;
}
The idea is that i and j are placed on the stack and you could find address of stack by using address of one more variable on the stack.
You should note that sometimes it is impossible to find addresses of i and j because compiler will not allocate memory for them because of optimization. This once again confirms the fact that you should not try to write such code.
On windows this can be done using the _AddressOfReturnAddress intrinsic. This function gives you the address on the stack which contains the return address. the address of i,j would be a constant negative offset from that address.
Notice that any such "solution" is highly non portable and would probably fail in many cases. one such case is if the compiler decides for some reason to make i and j registers. The compiler may decide to do this since you never explicitly take the address of i or j so as far as it is concerned, its safe. In this case i,j don't actually have addresses so you're going to get the address of something else on the stack and writing on it is very likely to crash your program.
I found this works in VC compiler..
the function name takes 2 int32 in the stack, then comes the definition of a.
int find_addr()
{
int a;
printf("&a = %u &i = %u & j = %u\n", &a, &a+4, &a+3);
}