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);
Related
This question already has answers here:
What happens when you call data() on a std::vector<bool>?
(4 answers)
Closed last year.
I required your help for a very strange behaviour that I can't understand.
I wrote a simple usage of vector.data :
void* ptr = NULL; // really initialized somewhere else
bool* boolPtr = NULL;
boolPtr = ((std::vector<bool>*)ptr)->data();
and when I compile (with -std=c++17) I got the error
void value not ignored as it ought to be
I try a lot a things but it seems that each time I call, from a casted vector (from void*), the data() method return a void instead of a bool*.
What did I miss ?
vector<bool> is not a proper vector. As weird as that sounds, that's the way it is. It can't give you a pointer to its internal bool array, because it doesn't have one, since it stores the values packed into single bits.
This question already has answers here:
Can we change the value of an object defined with const through pointers?
(11 answers)
Closed 5 years ago.
I'm learning C++ from past few days and when learning about the const qualifier tried the below:
const int m = 10;
int main()
{
int* lptr;
int* gptr;
const int i = 20;
lptr = (int *)&i;
*lptr = 40; //line 1
cout<<i<<endl;
cout<<*lptr<<endl;
*gptr = (int*)&m;
*gptr = 50; //line 2
cout<<m<<endl;
cout<<*gptr<<endl;
}
Here, since I'm casting the const int* to int* explicitly, the code compilation is perfectly alright. In line 1, I'm surprised to see that there is no run time error(access violation). But in line 2 there is a run time error saying write access violation (which is expected as const variables are placed in ro memory). But here why the local const variable is allowed to be modified through lptr. Is there nothing like a read only memory on the stack also? (and if it doesn't then how safe is using const local variables as it can be modified with a pointer)
*I'm using MSVC++ 14.0 *
I know that const variables are not meant to be modified, but since I'm leaning from basics I'm exploring the different ways
Just because you can cast away const and then write to a const variable through a pointer to non-const does not make it legal. In fact it is undefined behaviour and your program is ill formed and has no meaning. The compiler is free to generate whatever code it feels like in that case.
This question already has answers here:
Array with size 0 [duplicate]
(4 answers)
What is the purpose of allocating a specific amount of memory for arrays in C++?
(5 answers)
Closed 5 years ago.
Im reading up for a exam in C++ and just fideling around in order to get a better sense of the language. My understanding is that arrays in c++ are defined with a fixed length either before run time or dynamically. Knowing this I don't understand why C++ accepts this. I wouldn't think that it would be possible to add element to an array of length 0;
int * TestArray = new int[0];
TestArray[0]=10;
TestArray[1]=20;
TestArray[2]=30;
Writing to array elements outside of the valid size is Undefined Behaviour. It's a bug and your program is ill formed. But the compiler is not required to issue a diagnostic (although most will with the right warning options).
It's your responsibility to follow the rules.
You may not access any elements in a zero sized array. It results in undefined runtime behavior.
However, zero sized arrays are allowed for various reasons.
First, it allows you to make functions less complicated by skipping size checks:
void f(size_t n)
{
int * ptr = new int[n];
//...
delete[] ptr;
}
instead of:
void f(size_t n)
{
if (n>0)
{
int * ptr = new int[n];
//...
delete[] ptr;
}
}
Second, the intent was to make it easy for compiler writers to implement new using malloc, and this is the defined behavior for malloc.
The GCC c compiler docs give this reason:
"Zero-length arrays are allowed in GNU C. They are very useful as the last element of a structure that is really a header for a variable-length object: "
struct line {
int length;
char contents[0];
};
struct line *thisline = (struct line *)
malloc (sizeof (struct line) + this_length);
thisline->length = this_length;
[without it], you would have to give contents a length of 1, which means either you waste space or complicate the argument to malloc.
My professor told me that because c++ and c can access and write outside of array bounds,it is one of the main reasons they are used to create operating systems. For example you can even do something like
arr[-1]=5;
I believe it is worth mentioning.However this can lead to undefined behavior.
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() {
This question already has an answer here:
Pointer to a specific fixed address
(1 answer)
Closed 3 years ago.
An interesting discussion about this started here but no one have been able to provide the C++ way of doing:
#include <stdio.h>
int main(void)
{
int* address = (int *)0x604769;
printf("Memory address is: 0x%p\n", address);
*address = 0xdead;
printf("Content of the address is: 0x%p\n", *address);
return 0;
}
What is the most appropriate way of doing such a thing in C++?
In C++, always prefer reinterpret_cast over a C-cast. It's so butt ugly that someone will immediately spot the danger.
Example:
int* ptr = reinterpret_cast<int*>(0x12345678);
That thing hurts my eyes, and I like it.
There is NO standard and portable way to do so. Non-portable ways may include reinterpret_cast(someIntRepresentingTheAddress).
This will work:
void *address=(void *) 0xdead; // But as mentioned, it's non-standard
address=(void *) 0xdeadbeef; // Some other address
In C++, I prefer to declare the pointers as constant pointers in a header file:
volatile uint8_t * const UART_STATUS_REGISTER = (uint8_t *) 0xFFFF4000;
In the C language, this is usually implemented using a macro:
#define UART_STATUS_REGISTER ((volatile uint8_t * const) 0xFFFF4000)
In the rest of the source code, the memory address is referenced via the symbolic name.
I would add that you can call the placement operator for new if you want an objects constructor called when assigning it at the specified address:
int *pLoc = reinterpret_cast<int*>(0x604769);
int *address = new (pLoc) int (1234); // init to a value
This is also used for memory caching objects. Create a buffer and then assign an object to it.
unsigned char *pBuf = new unsigned char[sizeof(CMyObject) + alignment_size];
allign_buf(pBuf);
CMyObject *pMyObj = new (pBuf) CMyObject;