简体   繁体   中英

Can I use a variable to specify the size of a struct member array?

I am trying to represent a HD page in a struct. The code below does not work, because page_size is not a constant.

int page_size = 4096;

struct page {

  char data[page_size];

  /* some methods */
}

Since I am building and randomly accessing arrays of pages, it would be nice if I could treat a page as a fixed length struct of size page_size. If possible, I would like to read page_size from a configuration file at the start of the program, or get it from the OS (eg, GetDiskFreeSpace() on Windows). Obviously, there are only a handful of realistic page sizes, but I can't think of a way to exploit that.

Any help is appreciated.

Frank

Nope. As you've found out, you can't. The compiler needs to know the size of its data structures, reliably and constantly, to do its work.

I'm assuming that the page data is not the only content of your struct . You probably have some header / management information about your page in there along with the text.

The common solution would be for your struct to contain a char * pointing at the actual text. That text could then be in a chunk of memory malloc() 'd or calloc() 'd to whatever size you need. Alas, this means you'll have to remember to move the external text around along with your struct whenever you do operations that move the struct around, and memory manage the text when you get rid of the struct... the usual C headaches.


EDIT

There are sensible "standard" ways to do this kind of thing. Here is a suggestion:

typedef char *page_ptr;
int page_size = discover_page_size();
int max_page_count = discover_max_page_count();
int pages_stored = 0;
page_ptr *page_pointers = calloc(max_page_count, sizeof(page_ptr));
char *pages = calloc(max_page_count * page_size, sizeof(char));
page_pointers[0] = pages;
int i;
for (i=1; i<max_page_count; i++) {
    page_pointers[i] = page_pointers[i-1] + page_size;
}

Now you can treat page_pointers as an array of pages, doing stuff like

read(filedesc, page_pointers[page_count++], page_size);

or

memmove(page_pointers[69], page_pointers[42], page_size);

You have an overhead of one pointer per page (surely acceptable), and your pages are physically contiguous in memory. What more could you ask? :)

{C++}

If you want size to be determined at runtime why can't you use std::vector ?

int page_size = 4096; //or any variable

class page{

    std::vector<char> PAGE;
    public:

    page():PAGE(page_size){}
};

C and C++ requires array lengths to be compile time constants. C99 introduced variable length arrays to C, but I'm not sure if you can use them in structures.

[C++]

You could do:

int page_size = 4096;

struct page 
{
    char *pData;
    page() : pData(new char[page_size])
    {
    }
    ~page()
    {
        delete[] pData;
    }

  /* some methods */
}

Instead.

you can use

#define PAGE_SIZE 4096

struct page {

  char data[PAGE_SIZE];

  /* some methods */
}

And using autoconf automake you can customize PAGE_SIZE

If it's just text you want, the easiest way is probably

struct page {

  std::string data;

  /* some methods */
}

That's why I asked C or C++, as this isn't available in C.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM