I wanted a heap allocated buffer common to a class (to use as a scratchpad during computations). At some point I may free and then reallocate the buffer if it is not large enough. I wanted the buffer to exist without having to call a "myclass::initialize();" in main(); I came up with the following code that compiles and works well for my purpose.
My questions are: Why does this code compile correctly? Why is malloc() allowed to be outside of main() or any other function? Is the compiler interpreting this somehow and removing the malloc?
Code compiled on linux 64bit using "g++ example.cpp" and checked with valgrind
// example.cpp
#include <cstdio>
#include <cstdlib>
class myclass {
public:
static char* pbuf; // buffer
static unsigned int length; // buffer length
const static unsigned int chunk_size; // allocation chunck size
};
// set constants and allocate buffer
const unsigned int myclass::chunk_size = sizeof(long unsigned int) * 8;
unsigned int myclass::length = chunk_size; // start with smallest chunk
char* myclass::pbuf = (char*)malloc(sizeof(char)*myclass::length);
int main() {
// write to buffer (0 to 63 on 64bit machine)
for (int i = 0; i < myclass::length; i++) {
*(myclass::pbuf+i) = i;
}
// read from buffer (print the numbers 0 to 63)
for (int i = 0; i < myclass::length; i++) {
printf("%d\n", *(myclass::pbuf+i));
}
free(myclass::pbuf); // last line of program
}
Thanks for the answers. Sound like this is more common than I thought. "Functions calls are allowed in static initializers". This leads me to a slightly modified version catching a possible malloc error:
#include <cstdio>
#include <cstdlib>
class myclass {
public:
static char* pbuf; // buffer
static unsigned int length; // buffer length
const static unsigned int chunk_size; // allocation chunck size
static void* malloc_buf(unsigned int);
};
// set constants and allocate buffer
const unsigned int myclass::chunk_size = sizeof(long unsigned int) * 8;
unsigned int myclass::length = chunk_size; // start with smallest chunk
//char* myclass::pbuf = (char*)malloc(sizeof(char)*myclass::length);
char* myclass::pbuf = (char*)myclass::malloc_buf(sizeof(char)*myclass::length);
void* myclass::malloc_buf(unsigned int N) {
void* buf = malloc(N);
if (!buf) exit(EXIT_FAILURE);
return buf;
}
int main() {
// write to buffer (0 to 63 on 64bit machine)
for (int i = 0; i < myclass::length; i++) {
*(myclass::pbuf+i) = i;
}
// read from buffer (print the numbers 0 to 63)
for (int i = 0; i < myclass::length; i++) {
printf("%d\n", *(myclass::pbuf+i));
}
free(myclass::pbuf); // last line of program
}
It's just doing static initialization (initialization before main is called). Static initializers are allowed to call functions.
main()
is just another function - which is why it has such specific requirements placed on it to allow it to be called properly.
Other things can and do happen before it gets called. Static initialization among them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With