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);
}
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
Hello guys so my question is can you help me to debug a simple c program with gcc and make it work?
The teacher gave me this code and I should debug it and make it work, i tried but without any help I can't do It.
I compiled it with g++ -g double_free.c -o double_free
The program crashes.
this is the code:
#include <stdlib.h>
#include <stdio.h>
#define ARRAY_SIZE 100000
int main(int argc, char* argv[])
{
int i, test=5;
int* buf = new int[100000];
for (i=0; i< ARRAY_SIZE; i++){
buf[i] = i;
}
int result = 0;
delete []buf;
printf("result: %d\n", result);
delete[] buf;
printf("test %d\n", test);
return 0;
}
Here's a laundry list of complaints I have about this code:
You delete buf twice. This is really the only item I can see that needs actual debugging. The fact that the name of the exercise is double_free is a dead giveaway to experienced coders that this is the issue.
On top of that:
You should either be a C coder or a C++ coder, not a C+ coder (that strange variant that doesn't appear to have fully made the transition). Other than code meant to compile in both C and C++ environments, there's no reason a C++ program should be using the legacy C headers and functions (such as stdio.h and printf).
You should use ARRAY_SIZE in all places where you need the size of that array, otherwise you risk changing it in one place and not the other.
Variables should be scoped as tightly as possible. In other words, get rid of the current i declaration and just use for (int i = ....
Neither result nor test are changed, nor is buf used for anything, so your entire program boils down to std::cout << "result: 0\ntest 5\n";.
There's little point to putting argv/c in your main declaration if you don't use them, just use int main().
It's a good idea to move away from raw pointers, and start using smart pointers - these can automagically deallocate themselves when they go out of scope, leading to easier memory management.
You used delete[] buf; twice.
Just delete it between both prints
This question already has answers here:
What are the barriers to understanding pointers and what can be done to overcome them? [closed]
(28 answers)
Closed 9 years ago.
I've always never fully understood pointers. I'm writing this dinky blackjack game for fun on the side of my studies, and I need confirmation that this use of pointers is legitimate so I can fully understand what they do.
currently this is an example of the program and function i'm using:
void dealcard(int hand){
hand+=rand()%10+2;
}
int()main{
int playerHand;
...
*blackjack stuff*
...
if(hit){
deal(hand);
}
now if I'm correct, the above would not work as I intend because the function uses a copy of the variable that is cleared before it can be applied to the original, and hand would never be changed.
if I changed it to something like
int b;
int *hand;
hand=&b;
and changed the function declaration to include the *, then that would be correct.
I'm really trying hard to understand pointers and i'd appreciate any help or confirmation on this so I can understand the basic usefulness of them.
That would be correct. It would also be C rather than C++ :-) The way you would do it in that case would be:
void dealcard (int *pHand) {
*pHand += rand() % 10 + 2;
}
:
int hand = 0;
dealcard (&hand);
C++ has this nifty thing called references which means you no longer have to perform the sort of addressing gymnastics required by C. You can write your function thus:
void dealcard (int &hand) {
hand += rand() % 10 + 2;
}
:
int hand = 0;
dealcard (hand);
And, as an aside, not really relevant to your question:
int()main{
is not one of the accepted signatures for main, I suspect you meant:
int main() {
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.
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
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.