【发布时间】:2015-11-17 21:46:39
【问题描述】:
我想要一个类共有的堆分配缓冲区(在计算期间用作暂存器)。在某些时候,如果缓冲区不够大,我可能会释放然后重新分配缓冲区。我希望缓冲区存在而不必调用“myclass::initialize();”在主要()中;我想出了以下代码,这些代码可以编译并很好地用于我的目的。
我的问题是:为什么这段代码编译正确?为什么 malloc() 允许在 main() 或任何其他函数之外?编译器是否以某种方式解释了这一点并删除了 malloc?
使用“g++ example.cpp”在 linux 64bit 上编译并使用 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
}
感谢您的回答。这样的声音比我想象的更常见。 “静态初始化程序中允许函数调用”。这使我得到了一个稍微修改的版本,发现了一个可能的 malloc 错误:
#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
}
【问题讨论】:
-
这是一件极其危险的事情。如果不同编译单元中的任何其他静态初始化程序访问
pbuf,则结果是不可预测的,并且可能会因不同的编译器、平台甚至使用相同编译器的相同代码的编译而异。见static order fiasco。 -
恭喜您的第一个问题获得四票赞成。我们希望您在 StackOverflow 过得愉快。
-
main() 中的示例代码具有误导性(抱歉)。实际上,类成员函数是唯一访问 pbuf 数据的函数。在我自己的脑海中,我一直将缓冲区称为“便签本”。这个想法是成员函数可以使用可用的暂存器缓冲区,因为它“可用”且“足够大”。如果它太小,则可以调整它的大小,但只要需要,它就会保持“大”。我的想法是我只留下缓冲区,以便成员函数有一个临时区域可以使用......
标签: c++ class malloc variable-declaration