Jump to content
  • Advertisement
Sign in to follow this  
Psychopathetica

Empty Array In Structures

This topic is 2092 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey there. I wanna be able to have some way of being able to use an empty array inside a structure to be reinitialized later on. The reason why is cause it will have an unknown number of elements until a file is loaded, and then I can reinitialize the array to an appropriate size and start storing data. The only thing I can think of for a solution since in C++ you cant have empty arrays in structures is to make a pointer to a variable in the structure:

#include <iostream>
using namespace std;

struct Test_Structure
{
     unsigned char *myarray;
};

Test_Structure test;

int main()
{
	unsigned char some_other_array[10];
	test.myarray = new unsigned char[10];
	cout << "test.myarray: " << sizeof(test.myarray) << endl;
	cout << "some_other_array: " << sizeof(some_other_array) << endl;
	system("pause");
	return 0;
}

However if you were to run that, it only shows the size of the pointer rather than the whole array. Can I still the pointer as an array? Or is there another way around using empty arrays from structures?

Share this post


Link to post
Share on other sites
Advertisement

You can have an empty array at the end of a structure like:

struct Test_Structure {
   const int32_t some_data_0;
   const uint32_t array_of_some_sort[];
};
I find these can be useful when using memory mapped files.  In many file formats you'll have a header to a block of data, and then a variable number of some item following the header.  These sorts of trailing empty arrays can make traversing the files very easy I found.  These sorts of things are good when the memory is allocated through some other means.  As Hodgman pointed out, if you intend to allocate the memory your self, use a std::vector or similar container.

 

I would take note that const makes you unable to change the data of this structure, so it would need to be initialized in a constructor initializer list, and also that uint32_t array[] is equal to typing uint32_t* array, but the latter makes it a bit more clear as to what the variable is: a pointer, as there's no such thing as an empty array in C++. Using such a construct is fine in C, but it'd personally avoid it in C++, considering there's a safe way to do it which avoids accidental memory leaks.

I failed at reading the specific use case, as is explained in later posts, which now makes sense to me. Learn something new everyday!

Edited by Strewya

Share this post


Link to post
Share on other sites
Ryan_001 already explicitly stated his use case for these structs (namely when working on data provided through memory mapped files). In this context, const makes a lot of sense.

I'd also like to point out that an open array and a pointer are not the same thing. The open array once again works perfectly for his use case, a pointer would not work at all.

Share this post


Link to post
Share on other sites

You can have an empty array at the end of a structure like:

struct Test_Structure {
   const int32_t some_data_0;
   const uint32_t array_of_some_sort[];
};
I find these can be useful when using memory mapped files.  In many file formats you'll have a header to a block of data, and then a variable number of some item following the header.  These sorts of trailing empty arrays can make traversing the files very easy I found.  These sorts of things are good when the memory is allocated through some other means.  As Hodgman pointed out, if you intend to allocate the memory your self, use a std::vector or similar container.

 

Yep. I'm using this frequently in resource management, rendering jobs, and similar tasks, because at that level things are just blobs with a specific header. Only certain sub-systems are able to interpret the blob correctly.

Share this post


Link to post
Share on other sites

Thanks for the solutions. I tried using vector but theres a problem. If you use a variable declared from vector, you wont be able to use that variable to extract data from a file because you cant convert a vector(unsigned char) to (char *). I am using ifstream file and file.read to get the data.

Edited by Psychopathetica

Share this post


Link to post
Share on other sites

you could first get the filesize, then preallocate enough space in the vector and push back chunks of the file that you read into a temporary buffer.

 

Edit: Because I haven't programmed in c++ for a while and your problem has piqued my interest. Here is the shortest form I think:

//... constructed before
std::vector<char> content();

//...load data
std::ifstream inputFile("input.dat", std::ios::binary);
content.assign(std::istreambuf_iterator<char>(inputFile)), std::istreambuf_iterator<char>());
Edited by Madhed

Share this post


Link to post
Share on other sites

Thanks for the solutions. I tried using vector but theres a problem. If you use a variable declared from vector, you wont be able to use that variable to extract data from a file because you cant convert a vector(unsigned char) to (char *). I am using ifstream file and file.read to get the data.

Vec.resize(fileSize);
char* buffer = (char*)&Vec[0]

Share this post


Link to post
Share on other sites

Or the long overdue C++11 way:

 

char* buffer = Vec.data();

 

edit: okay, char to unsigned char means not getting rid of the cast. Which means being torn between the "proper" way of the ugly static_cast<char>() or the "evil" easy C-style cast (char*).

Edited by Trienco

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!