我有以下代码,我无法理解main中一行后的状态。
#include <iostream>
typedef unsigned long size_t;
const int MAX_BUFFER=3;
int buf[MAX_BUFFER]={0}; //Initialize to 0
int location=0;
struct Scalar {
int val;
Scalar(int v) : val(v) { };
void* operator new(size_t /*not used*/) {
if (location == MAX_BUFFER) {
throw std::bad_alloc();
} else {
int* ptr = &buf[location];
if ( buf[location] == 0) {
location++;
} else {
return ptr;
}
}
}
void operator delete(void* ptr) {
size_t my_loc = (int*)ptr - buf;
buf[my_loc] = location;
location = my_loc;
}
};
int main() {
Scalar *s1 = new Scalar(11);
cout << buf[0];
}
为什么此代码末尾的数组buf
在...处包含值11?
我不确定val
输入在哪里发挥作用。
答案 0 :(得分:2)
我不明白你为什么只在分配后有条件地增加location
,如果增加location
,那么该函数不会执行未定义行为的return
语句
除非对象仅以完全相反的分配顺序释放,否则您的释放策略将完全中断。另外,在将数组元素用于一次分配之后,由于在deallocator中的赋值,它将不再被使用。
至于实际问题:分配的第一个Scalar
分配在与缓冲区相同的位置,因此第一个Scalar
和buf[0]
共享相同的内存。由于它们都由单个int
组成,因此对一个写入可能是另一个可读的。当您构造Scalar
时,它会将值11
分配给共享内存。我认为这样做是不明确的行为,但我不确定。
答案 1 :(得分:2)
由于
,值11进入缓冲区Scalar(int v) : val(v) { };
获取参数并将其复制到成员val
。
如果类实例是在缓冲区的地址处分配的(由于自定义的operator::new (size_t)
实现),那么它的第一个成员可能会在第一个数组元素中结束。
请注意,由于Mooing Duck已经指出的几个原因,此代码完全被破坏了。