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() {
Related
This question already has answers here:
Why is it that we can write outside of bounds in C?
(7 answers)
Is accessing a global array outside its bound undefined behavior?
(8 answers)
Undefined, unspecified and implementation-defined behavior
(9 answers)
Closed 11 months ago.
I wrote a code for entering element and displaying the array at the same time. The code works but since char A[4] is static memory why does not it terminate/throw error after entering more than four elements? Code:
#include <iostream>
using namespace std;
void display(char arr[],int n)
{
for(int i=0; i<n; i++)
cout<<arr[i]<<" ";
return;
}
int main()
{
char A[4];
int i=0;
char c;
for(;;)
{
cout<<"Enter an element (enter p to end): ";
cin>>c;
if(c=='p')
break;
A[i]=c;
i++;
display(A,i);
system("clear");
}
return 0;
}
Writing outside of an array by using an index that is negative or too big is "undefined behavior" and that doesn't mean that the program will halt with an error.
Undefined behavior means that anything can happen and the most dangerous form this can take (and it happens often) is that nothing happens; i.e. the program seems to be "working" anyway.
However maybe that later, possibly one million instructions executed later, a perfectly good and valid section of code will behave in absurd ways.
The C++ language has been designed around the idea that performance is extremely important and that programmers make no mistakes; therefore the runtime doesn't waste time checking if array indexes are correct (what's the point if the programmers never use invalid ones? it's just a waste of time).
If you write outside of an array what normally happens is that you're overwriting other things in bad ways, possibly breaking complex data structures containing pointers or other indexes that later will trigger strange behaviors. This in turn will get more code to do even crazier things and finally, some code will do something that is so bad that even the OS (that doesn't know what the program wants to do) can tell the operation is nonsense (for example because you're trying to write outside the whole address space that was given to the process) and kills your program (segfault).
Inspecting where the segfault is coming from unfortunately will only reveal what was the last victim in which the code is correct but that was using a data structure that was corrupted by others, not the first offender.
Just don't make mistakes, ok? :-)
The code works but since char A[4] is static memory why does not it terminate/throw error after entering more than four elements?
The code has a bug. It will not work correctly until you fix the bug. It really is that simple.
This question already has answers here:
How do C++ class members get initialized if I don't do it explicitly?
(8 answers)
Closed 1 year ago.
I'm doing C++ tests for my certification exam and I came across this exercise that i don't understand:
(the question is what is the output of the following program)
#include <iostream>
using namespace std;
class A {
public :
float v;
float set(float v) {
A::v += 1.0;
A::v = v+1.0;
return v;
}
float get(float v){
v +=A::v;
return v;
}
};
int main()
{
A a;
cout<< a.get(a.set(a.set(0.5)));
return 0;
}
I expected to have an error on the first line of the set function since A::v was never initialized, but my program compiles and it seems that A::v has value 0 by default..
Could someone please explain why there is no compilation error?
Like you mentioned, the first line of set used A::v, which was never initialized before. However, that itself doesn't produce an error, it is undefined behavior. What it means is the compiler may initialize it for you, or it might just pickup a random number it sees on the memory, or whatever they are pleased to. The C++ standard doesn't say what needs to happen, so it left the compiler to decide whatever is easy.
However, whatever happens on that line shouldn't matter too much in your code, in most cases. The reason is A::v will be re-assigned to v + 1 on the next line. So it should almost always print 2 at the end.
This question already has answers here:
C++ return value without return statement
(6 answers)
Closed 6 years ago.
I am confused with the following output in C++
int add()
{
int c = 2+3;
}
int main()
{
int x = add();
cout << x;
return 0;
}
This prints 5.even if we do not write return statement.
How this is managed in C++.
Please help.
This is UB. You're right to be confused - this can work one day and fail the next. Don't rely on undefined behavior.
If you want to know why it works, it's because parameters & return values are passed on a data structure called stack (well - usually; sometimes passed in the same register). Similarly, most implementations use this same stack for locals. Therefore, the int in add will be located in the same place as where the return value is expected (by your specific implementation) and your implementation doesn't invalidate memory when your int there is destructed. But it's still destructed, it's still UB and it might break in any second.
As the comments wrote, you might turn on warnings to avoid this kind of error.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I am making a simple Lottery program - and am struggling with implementation. I have a class called 'Ticket Line' this class simply holds 6 numbers that the player is playing a lottery for.
What I want to do, is generate 6 randomly (got function for this already) and then store that in another class as values. To do this, I am using the following code:
class Draw
{
private:
int drawID;
TicketLine* DrawnNumbers;
bool drawn;
}
When a Draw is completed I want to generate the Random Numbers ( from the TicketLine class) and then for the Draw to be able to store those numbers into its Draw File.
How would I be able to access the functionality of the DrawnNumbers class - and store the results from the getTicketNumbers.getTicketLine()function.
int* getTicketNumbers(void) { return DrawnNumbers->getTicketLine();};
The program crashes the following code:
//int *ptr[6] = getTicketNumbers();
int *ptr[6] = getTicketNumbers();
for (int x = 0; x < 6; x++){
cout << ptr[x];
}
TicketLine class:
private:
int select[6]; //Array of Ticket Numbers.
int* getTicketLine(void) { return select; };
I am willing to offer a couple of virtual beers to the solution. I am as yet to find a good online pub - if you know of one then please do let me know :-)
Thanks,
Without knowing any more, this line:
int *ptr[6] = getTicketNumbers();
is very suspect.
Why? Well, we haven't seen the implementation of getTicketNumbers so we don't know if it's actually allocating memory for 6 and returning such an array.
Also, you are printing the values of pointers here:
for (int x = 0; x < 6; x++){
cout << ptr[x];
}
Where, if you intended to actually print the int values, you'd say something like this:
for (int x = 0; x < 6; x++){
cout << *(ptr[x]);
}
My guess is that you are either:
Going out of bounds of an array that was (not) allocated, or,
Modifying actual pointer values somewhere instead of the integers they point to (as indicated by your lack of dereferencing ptr[x] in your print statement)
Edit
With more information, it seems you probably meant to say this:
int *ptr = getTicketNumbers();
instead of this:
int *ptr[6] = getTicketNumbers();
You should probably be doing some sanity checks as well to make sure that select is actually filled before calling that function (maybe giving it a default value of {0,0,0,0,0,0} in the constructor)
DrawnNumbers doesn't appear to be pointing to anything yet. It's a pointer, but to what?
Also, be careful about returning arrays that way. If the object or stack frame that the array resides in goes away, you'll be left pointing to bad things.
This question already has answers here:
Pointer arithmetic when void has unknown size [closed]
(8 answers)
Closed 9 years ago.
I have some old code I inherited that I am maintaining and want to change as little as possible. It does not compile with newer compilers.
There is more to the code but basically the idea, I think, (regardless how bad) is to pass a void* to the start of a table of records of arbitrary record size. I do not want to make changes outside of this function since it gets ugly. I think I just want to cast to an unsigned char* and do the addition and then cast back to void* but I am having trouble figuring out the right casting etc.
Any suggestions?
Here is the original code:
foo(const void* recordArrayBasePtr ,ubin32 sizeOfStruct)
{
void * recordPtr;
int row = 9; //for example
recordPtr = const_cast<void *>( recordArrayBasePtr ) + sizeOfStruct * row;
}
You want to cast to char*, which is done with reinterpret_cast and not with const_cast. But considering that this is really C code, you can just as well use C-style casts which will be less of a hassle to write:
recordPtr = (void*)((char*)recordArrayBasePtr + sizeofStruct * row);