D3DFORMAT *arr = NULL;
This is the reference to the array which is supposed to hold D3DFORMAT typed values.
How do I allocate the memory for this array whose size is defined by a variable
unsigned int arrsize;
Should I calculate the size of array in bytes as = sizeof(D3DFORMAT)*arrsize;
And than use memset().?
Plz correct me if I am wrong. Or if tere is a cleaner better C++ method to do this. ?
IN advance. Thanks
"cleaner better C++ method" is to use a std::vector
unsigned int arrsize = 10;
std::vector <D3DFORMAT> array (arrsize );
to cast it to void*
void* p = (void*)(&array[0]);
you will also want to have your values be 0 by default, so just add one more parameter to the constructor
unsigned int arrsize = 10;
std::vector <D3DFORMAT> array (arrsize, 0);
Like this
D3DFORMAT* arr = new D3DFORMAT[arrsize];
memset might work, or it might crash your program. It all depends on how D3DFORMAT has been defined. Can you post the definition of D3DFORMAT?
Just noticed you asked for a better method. The better method very likely is
std::vector<D3DFORMAT> arr(arrsize);
but again, it does depend on how D3DFORMAT is defined.
Related
#include <iostream>
char** make2D(const int dim1, const int dim2)
{
char* toAlloc;
const int size = (dim1 * dim2) + dim2;
toAlloc = new char[size];
for(int i = 0; i < dim2; i++)
{
toAlloc[i] = reinterpret_cast<char>(&toAlloc[(dim2 + (dim1 * i))]);
}
return reinterpret_cast<char**>(toAlloc);
}
int main(void)
{
int dim1 = 8;
int dim2 = 10;
char** array2D = make2D(dim1, dim2);
for (int i = 0; i < dim2; ++i)
{
array2D[i][i % dim1] = i + 100; // << Crash
}
return 0;
}
I was trying to allocate two dimensional array by a single allocation.
So, my algorithm was, first 10(which is dim2 in this code) items has pointer to first item of each rows.
When I was try this by pointer to 'int',
int** make2D(const int dim1, const int dim2)
{
int* toAlloc;
const int size = (dim1 * dim2) + dim2;
toAlloc = new int[size];
for(int i = 0; i < dim2; i++)
{
toAlloc[i] = reinterpret_cast<int>(&toAlloc[(dim2 + (dim1 * i))]);
}
return reinterpret_cast<int**>(toAlloc);
}
int main(void)
{
int dim1 = 8;
int dim2 = 10;
int** array2D = make2D(dim1, dim2);
for (int i = 0; i < dim2; ++i)
{
array2D[i][i % dim1] = i + 100;
}
return 0;
}
it works fine but when I do this in char, it crashes in commented line in above code.
My thought of crashing was when I do reinterpret_cast, something happens because of memory size gap between pointer(8byte) and char(1byte).
So like, sounds like ridiculous... changing pointer(8byte) to int(4byte) was fine, but when I do cast more dramatically(8byte to 1byte), it causes some problems...
I have no idea why char doesn't work but int works.
Could you give some advice to make char case works?
To answer the question yes there is a difference, a huge one, on many platforms a pointer might fit into an int, on very few platforms it will fit into a char. On modern PCs which are 64-bit none are safe ways to store a pointer.
Use containers such as vector or array if the size is static.
Try something like:
array<array<T, dim2>, dim1> variable{};
if you actually want a 2-dimensional array of type T; since you seem to need an array of pointers try something like:
array<array<T *, dim2>, dim1> variable{};
This will take care to make an array of the appropriate type to store pointers in for your platform, no matter how big pointers actually are, obviously you should replace T with the proper type of the data you want to point to, this will ensure pointer math is done properly for you.
Array types will have their size calculated at compile time, if you need dynamic sizes you should use vector, after allocation call resize on the vector and all sub-vectors to make sure you allocate all the memory in as few passes as possible.
Please also don't use reinterpret_cast, or c-style casts, it's a recipe for disaster unless you know very well what you're doing.
Don't know what book you're reading or who is teaching you C++ but please change your knowledge source.
Using raw owning pointers is discouraged and the way you're using them is wrong in so many ways.
Never store a pointer in anything but a pointer type. Even in plain C you should cast to at least void * if you need to cast at all.
Please read about unique_ptr or shared_ptr if you really want to store/pass pointers around directly.
If you insist on using raw pointers for containers please try building your code with sanitizers such as address sanitizer, memory sanitizer (these are supported at least by clang and gcc, possibly more compilers these days)
Issue is "incompatibility" of size of objects:
sizeof(char) is 1
sizeof(int) is generally 4 or 8 (but at least 2).
sizeof(T*) which is generally 4 or 8, std::uintp_t can hold void* value, which is not necessary the case with int (and even less with char).
You cannot store safely void* into char or int. It happens it's working for you for int, but it is not portable.
reinterpret_cast is generally the wrong tool.
Simpler would be to create a class Matrix, with std::vector<T> and accessor to fix indexing. (You might even have proxy to allow m[2][3] syntax).
With owning raw pointer, you need need placements new, and provide correct deleter...
just I want to ask how can I pass array size to throw function to set size of my game recoreds the only reason I am not using vector because I will base this recored to PMI lib and it doesn't support C++ Constrainers because it written in C that's why I use array
void playGame(int max_streak_length)
{
int tracker =0 ;
const int arrsize = max_streak_length;
int gameRecored[arrsize]={0};
while( tracker < 4)
{
Craps games;
if( games.Play()== true)
{
tracker++;
}
else
if(tracker >0)
{
gameRecored[tracker-1]++;
tracker = 0;
}
}
gameRecored[tracker-1]++;
int v= 0;
}
C++ does not support the variable length array feature available in C.99. However, C++ offers std::vector<> which is as easy to use, and some may say safer.
std::vector<int> gameRecored(arrsize, 0);
You can use gameRecored as an array like you do in your current code, and it will clean itself up when the function call returns.
you can't not define an array whose size is a VARIABLE. If you want a dynamic size, you should use operator new, just like this:
int mysize = 10;
int* array = new int[mysize];
the variable mysize can be a dynamic number, such as function parameter.
If your array will never change its size, you can use :
int array[10];
remember, if you use operator new, you must use operator delete to delete your array when you don't need it.
Hop can help you.
I am trying to use XCode for my project and have this code in my .h:
class FileReader
{
private:
int numberOfNodes;
int startingNode;
int numberOfTerminalNodes;
int terminalNode[];
int numberOfTransitions;
int transitions[];
public:
FileReader();
~FileReader();
};
I get a "Field has incomplete type int[]" error on the terminalNode line... but not on the transitions line. What could be going on? I'm SURE that's the correct syntax?
Strictly speaking the size of an array is part of its type, and an array must have a (greater than zero) size.
There's an extension that allows an array of indeterminate size as the last element of a class. This is used to conveniently access a variable sized array as the last element of a struct.
struct S {
int size;
int data[];
};
S *make_s(int size) {
S *s = (S*)malloc(sizeof(S) + sizeof(int)*size);
s->size = size;
return s;
}
int main() {
S *s = make_s(4);
for (int i=0;i<s->size;++i)
s->data[i] = i;
free(s);
}
This code is unfortunately not valid C++, but it is valid C (C99 or C11). If you've inherited this from some C project, you may be surprised that this works there but not in C++. But the truth of the matter is that you can't have zero-length arrays (which is what the incomplete array int transitions[] is in this context) in C++.
Use a std::vector<int> instead. Or a std::unique_ptr<int[]>.
(Or, if you're really really really fussy about not having two separate memory allocations, you can write your own wrapper class which allocates one single piece of memory and in-place constructs both the preamble and the array. But that's excessive.)
The original C use would have been something like:
FileReader * p = malloc(sizeof(FileReader) + N * sizeof(int));
Then you could have used p->transitions[i], for i in [0, N).
Such a construction obviously doesn't make sense in the object model of C++ (think constructors and exceptions).
You can't put an unbound array length in a header -- there is no way for the compiler to know the class size, thus it can never be instantiated.
Its likely that the lack of error on the transitions line is a result of handling the first error. That is, if you comment out terminalNode, transitions should give the error.
It isn't. If you're inside a struct definition, the compiler needs to know the size of the struct, so it also needs to know the size of all its elements. Because int [] means an array of ints of any length, its size is unknown. Either use a fixed-size array (int field[128];) or a pointer that you'll use to malloc memory (int *field;).
Why we can do something like
for(int i = 0; i < destination->imageSize; i=i+3)
{
buffer[2] = destination->imageData[i];
buffer[1] = destination->imageData[i+1];
buffer[0] = destination->imageData[i+2];
buffer+=3;
}
but we can not do
char buffer[destination->imageSize];
And how to such thing?
Sorry - I am quite new to C++...
BTW: my point is to create a function that would return a char with an image. If I'd use mem copy how do I delete returned value?
I have to ask, why do you think they're at all related? If you couldn't index an array by runtime variable, it'd be pretty useless for there to even be arrays. Declaring a variable of a size governed by a runtime variable is entirely different and requires fundamental changes to the way the compiler manages automatic memory.
Which is why you can't do it in C++. This may change, but for now you can't.
If you really need a variable sized array you need to allocate one dynamically. You can do it the hard, f'd up way (char * buff = new char[size]...delete [] buff;), or you can do it the easy, safer way (std::vector<char> buff(size)). Your choice. You can't build it "on the stack" though.
char buffer[destination->imageSize]; declares a variable at compile time. At that time, the value of destination->imageSize is not yet known, which is why it doesn't work.
The expression buffer[2] = destination->imageData[i]; (or rather the buffer[2] thereof) is evaluated at run time.
You cannot return a local array. Everything you return will need to be free'd by someone.
The size of a local array must be constant. Always. This is because there is no special logic around arrays in C++. You can use some object collection of STL.
Hmm. Did you try creating a pointer or reference to destination->imageSize and passing that in for the index instead?
Using std::vector you can achieve what you desire. Your function can be defined something like this:
void readImage(std::vector<char>& imageData, std::string& filename)
{
size_t imageSize = 0;
//read file and load imageSize
imageData.resize(imageSize);
// load image into imageData using such as you in your question
for(int i = 0; i < destination->imageSize; i=i+3)
{
buffer[2] = destination->imageData[i];
buffer[1] = destination->imageData[i+1];
buffer[0] = destination->imageData[i+2];
buffer+=3;
}
}
For further improvements you could return a bool that indicates success or failure.
Regarding the cause of C2466, I don't have the official answer but you can declare char arrays with const variables only like so:
const int imageSize = 4242;
char imageData[imageSize]; // No C2466 error
I happened to ask myself a question about arrays in c++.
Well, we all know that arrays are fixed collections of something, I say fixed because it is necessary to declare array length when defining arrays.
Well, let's consider an example:
char myarray[10] = {'\0'};
int sz = sizeof(myarray); // It is supposed to be 10
Well, it is correct, 10 is the number returned by sizeof. This can be done by the compiler because he knows how much space it placed for that variable.
Now consider what happens in this situation:
void dosome(mystruct* arr) {
int elements = sizeof(arr)/sizeof(mystruct);
for (int i = 0; i < elements; i++) {
// Do something hoping no overflow will ever occur
}
}
Nice... but I suppose it can be overflow prone. If I pass to this function an array I created in a "normal" way, everything should be fine:
mystruct array[20];
dosome(array);
No problem. But if I do this:
mystruct* array = (mystruct*)malloc(80*sizeof(mystruct));
dosome(array);
WHAT HAPPENS???????????????????
I would like to understand how sizeof behaves, this function is evaluated at compile time right??? ok, what happens when I use not an array, but something very cumbersome like a block of data like that one? furthermore, I could realloc it woth another call to malloc and ask to dosome to process that datablock again. Will it work?
I could try it physically, but I would get some exact answer about the behavioir of sizeof.
Thank you.
it's wrong starting from the mystruct array[20] example. Because the function receives a pointer type, and not an array type, it cannot deduce the number of elements in the array. you are actually getting the size of a mystruct* when you perform sizeof(arr).
You can use templates to write functions which take arrays as parameters, but the suggested way in C++ is to use vectors, if I am not wrong.
The "way" to receive arrays as parameters would be to write something like:
template <int N> void somefunction(int (&v)[N]);
EDIT corrected the function declaration. oops.
void dosome(mystruct* arr) {
int elements = sizeof(arr)/sizeof(mystruct);
for (int i = 0; i < elements; i++) {
// Do something hoping no overflow will ever occur
}
}
What type does arr have in this example? mystruct*! And it's size is most likely 4 or 8. If you want to pass statically/automatically allocated arrays (not new'd) to functions preserving the size so that your trick works, pass by REFERENCE!
template <int N>
void dosome(mystruct (& arr) [N]) {
for (int i = 0; i < N; i++) {
// Do something . No overflow will occur
}
}
Also note this
int a[20];
sizof a; //equals to 20*sizeof(int)
int* b = new int [20];
sizeof b; //equals to sizeof pointer, most likely 4
sizeof is a compile-time operator. And here it computes only the size of a pointer.