当我尝试通过代码(uint64_t b == 1600)在c ++中创建3d dyn数组时:
uint64_t w = b / 25; // OK
uint32_t ***_3state = new uint32_t**[5]; //OK
for (int i = 0; i < 5; ++i)
_3state[i] = new uint32_t*[5]; //OK
for (int i = 0; i < 5; ++i)
for (int j = 0; j < 5; ++j)
_3state[i][j] = new uint32_t[w]; //memory access violation
此代码产生运行时内存访问冲突,从而在相应的行中停止执行(由代码中的注释标记)
请帮助我
甚至是单行
new int[w]
将导致运行时异常
如果我从我调用的类中截断了这段代码,然后将其放入main函数中,它将起作用(!)
从main()调用
char msg[]{ "hello" };
BitSet b_msg{ msg, 40 };
State* sha = new State(b_msg);
类状态(为了反映我的目的,我将状态更改为初始状态(_3state更改为_state)):
class State {
public:
enum class widthOfPermutation { b0 = 25, b1 = 50, b2 = 100, b3 = 200, b4 = 400, b5 = 800, b6 = 1600 };
enum class depthOfState { w0 = 1, w1 = 2, w2 = 4, w3 = 8, w4 = 16, w5 = 32, w6 = 64 };
State(BitSet& s) {
s = *keccak_c(512, bitset_concat(&s, new BitSet(new UCHAR[1]{ 0x40 }, 2)), 256);
}
void toState(BitSet* s, uint64_t b) {
uint64_t w = b / 25;
_state = new uint32_t**[5];
for (int i = 0; i < 5; ++i)
_state[i] = new uint32_t*[5];
for (int i = 0; i < 5; ++i)
for (int j = 0; j < 5; ++j)
_state[i][j] = new uint32_t[w];
for (int i = 0; i < 5; ++i)
for (int j = 0; j < 5; ++j)
for (int k = 0; k < w; ++k)
_state[i][j][k] = s->get_bit(w*(5 * j + i) + k);
}
BitSet* toString(uint64_t b) {
uint64_t w = b / 25;
BitSet * r = new BitSet(new unsigned char[b / 8], b);
for (int i = 0; i < 5; ++i)
for (int j = 0; j < 5; ++j)
for (int k = 0; k < w; ++k)
r->set_bit(w*(5 * j + i) + k, _state[i][j][k]);
return r;
}
void aTeta(uint64_t b) {
uint64_t w = b / 25;
uint32_t ***_state2 = new uint32_t**[5]{ new uint32_t*[5]{ new uint32_t[w] } };
for (int i = 0; i < 5; ++i)
for (int j = 0; j < 5; ++j)
for (int k = 0; k < w; ++k)
_state2[i][j][k] = _state[i][j][k];
uint32_t** c = new uint32_t*[5]{ new uint32_t[w] };
for (int i = 0; i < 5; ++i)
for (int k = 0; k < w; ++k)
c[i][k] = _state[i][0][k] ^ _state[i][1][k] ^ _state[i][2][k] ^ _state[i][3][k] ^ _state[i][4][k];
uint32_t** d = new uint32_t*[5]{ new uint32_t[w] };
for (int i = 0; i < 5; ++i)
for (int k = 0; k < w; ++k)
d[i][k] = c[mod((i - 1), 5)][k] ^ c[mod((i + 1), 5)][mod((k - 1), w)];
for (int i = 0; i < 5; ++i)
for (int j = 0; j < 5; ++j)
for (int k = 0; k < w; ++k)
_state2[i][j][k] = _state[i][j][k] ^ d[i][k];
delete[] _state;
_state = _state2;
}
void aRo(uint64_t b) {
uint64_t w = b / 25;
uint32_t ***_state2 = new uint32_t**[5]{ new uint32_t*[5]{ new uint32_t[w] } };
for (int i = 0; i < 5; ++i)
for (int j = 0; j < 5; ++j)
for (int k = 0; k < w; ++k)
_state2[i][j][k] = _state[i][j][k];
uint32_t x = 1, y = 0;
for (int t = 0; t <= 23; ++t) {
for (int k = 0; k < w; ++k) {
_state2[x][y][k] = _state[x][y][mod((k - (t + 1)*(t + 2) / 2), w)];
uint32_t temp = x;
x = y;
y = mod(2 * temp + 3 * y, 5);
}
}
delete[] _state;
_state = _state2;
}
void aPi(uint64_t b) {
uint64_t w = b / 25;
uint32_t ***_state2 = new uint32_t**[5]{ new uint32_t*[5]{ new uint32_t[w] } };
for (int i = 0; i < 5; ++i)
for (int j = 0; j < 5; ++j)
for (int k = 0; k < w; ++k)
_state2[i][j][k] = _state[i][j][k];
for (int i = 0; i < 5; ++i)
for (int j = 0; j < 5; ++j)
for (int k = 0; k < w; ++k)
_state2[i][j][k] = _state[mod(i + 3 * j, 5)][i][k];
delete[] _state;
_state = _state2;
}
void aXi(uint64_t b) {
uint64_t w = b / 25;
uint32_t ***_state2 = new uint32_t**[5]{ new uint32_t*[5]{ new uint32_t[w] } };
for (int i = 0; i < 5; ++i)
for (int j = 0; j < 5; ++j)
for (int k = 0; k < w; ++k)
_state2[i][j][k] = _state[i][j][k];
for (int i = 0; i < 5; ++i)
for (int j = 0; j < 5; ++j)
for (int k = 0; k < w; ++k)
_state2[i][j][k] = _state[i][j][k] ^
(_state[mod(i + 1, 5)][j][k] ^ 1) * _state[mod(i + 2, 5)][j][k];
delete[] _state;
_state = _state2;
}
uint32_t rc(uint64_t t) {
if (mod(t, 255) == 0) return 1;
uint32_t intSize = 8;
uint32_t* r = new uint32_t[intSize];
r[0] = 1;
for (int j = 0; j < intSize; ++j) r[j] = 0;
for (int i = 1; i <= mod(t, 255); ++i) {
++intSize;
uint32_t* temp = new uint32_t[intSize];
temp[0] = 0;
for (int j = 1; j < intSize; ++j) {
temp[j] = r[j - 1];
}
delete[] r;
r = temp;
r[0] = (r[0] ^ r[8]) & 0x1;
r[4] = (r[4] ^ r[8]) & 0x1;
r[5] = (r[5] ^ r[8]) & 0x1;
r[6] = (r[6] ^ r[8]) & 0x1;
--intSize;
}
uint32_t res = r[0];
delete[] r;
return res;
}
void aI(uint64_t b, uint64_t ir) {
uint64_t w = b / 25;
uint32_t ***_state2 = new uint32_t**[5]{ new uint32_t*[5]{ new uint32_t[w] } };
for (int i = 0; i < 5; ++i)
for (int j = 0; j < 5; ++j)
for (int k = 0; k < w; ++k)
_state2[i][j][k] = _state[i][j][k];
uint32_t* RC = new uint32_t[w];
for (int i = 0; i < w; ++i) RC = 0;
for (int j = 0; j <= uint64_t(log2(w)); ++j)
RC[uint64_t(pow(2, j) - 1)] = rc(j + 7 * ir);
for (int k = 0; k < w; ++k)
_state2[0][0][k] = _state2[0][0][k] ^ RC[k];
delete[] _state;
_state = _state2;
}
void rnd(uint64_t b, uint64_t ir) {
aTeta(b);
aRo(b);
aPi(b);
aXi(b);
aI(b, ir);
}
BitSet* keccak_p(BitSet* s, uint64_t b, uint64_t nr) {
uint64_t w = s->size_in_bits() / 25;
uint64_t l = (uint64_t)log2(w);
toState(s, s->size_in_bits());
for (int ir = 12 + 2 * l - nr; ir <= 12 + 2 * l - 1; ++ir)
rnd(b, ir);
return toString(b);
}
BitSet* keccak_f(BitSet* s, uint64_t b) {
uint64_t w = s->size_in_bits() / 25;
uint64_t l = (uint64_t)log2(w);
return keccak_p(s, b, 12 + 2 * l);
}
BitSet* sponge(uint64_t b, uint64_t nr,
uint64_t r,
BitSet* N,
uint64_t d) {
BitSet* p = bitset_concat(N, pad10_1(r, N->size_in_bits()));
uint64_t n = p->size_in_bits() / r;
uint64_t c = b - r;
BitSet ** p_strings = new BitSet*[n] {new BitSet(new UCHAR[r / 8], r)};
for (int i = 0; i < n; ++i)
for (int j = 0; j < r; ++j)
p_strings[i]->set_bit(j, (p->get_bit(i*r + j)));
BitSet* s = o(b);
for (int i = 0; i < n; ++i)
s = keccak_p(bitset_xor(s, bitset_concat(p_strings[i], o(c))), b, nr);
BitSet* z = new BitSet();
while (true) {
s->trunc(r);
z = bitset_concat(z, s);
if (d <= z->size_in_bits()) {
z->trunc(d);
return z;
}
s = keccak_p(s, b, nr);
}
}
BitSet* pad10_1(uint64_t x, uint64_t m) {
uint64_t j = mod(-int64_t(m) - 2, x);
return bitset_concat(bitset_concat(new BitSet(new UCHAR[1]{ 0x80 }, 1), o(j)), new BitSet(new UCHAR[1]{ 0x80 }, 1));
}
BitSet* keccak_c(uint64_t c, BitSet* N, uint64_t d) {
return sponge(1600, 24, 1600 - c, N, d);
}
~State() {
delete[] _state;
}
private:
uint32_t * ** _state;
};
和BitSet类:
BitSet* o(uint64_t s) { // get ptr to string of 0
BitSet* r = new BitSet(new unsigned char[s / 8], s);
for (int i = 0; i < s / 8; ++i)
r->set_byte(i, 0);
return r;
}
BitSet* bitset_xor(BitSet* x, BitSet* y) {
uint64_t s = x->size_in_bits();
BitSet* r = new BitSet(new unsigned char[s/8], s);
for (int i = 0; i < s; ++i)
r->set_byte(i, x->get_byte(i) ^ y->get_byte(i));
return r;
}
BitSet* bitset_concat(BitSet* x, BitSet* y) {
uint64_t s_x = x->size_in_bits();
uint64_t s_y = y->size_in_bits();
uint64_t s_r = s_x + s_y;
BitSet* r = new BitSet(new unsigned char[s_r % 8 ? s_r / 8 + 1 : s_r / 8], s_r);
int i_r = 0;
for (int i_x = 0; i_x < s_x; ++i_x, ++i_r)
r->set_bit(i_r, x->get_bit(i_x));
--i_r;
for (int i_y = 0; i_y < s_y; ++i_y, ++i_r)
r->set_bit(i_r, y->get_bit(i_y));
return r;
}
int64_t round_up(double x) { return x - int64_t(x) ? int64_t(x) + 1 : x; }
uint64_t mod(int64_t m, int64_t n) {
return (m % n + n) % n;
}
class BitSet { // bit string
public:
BitSet() { };
BitSet(void* byte_string, uint64_t size_in_bits)
: _size_in_bits{ size_in_bits }, _string{ byte_string } { };
void set_bit(uint64_t index, uint32_t value) {
reinterpret_cast<unsigned char*>(_string)[index / 8] = value ?
reinterpret_cast<unsigned char*>(_string)[index / 8] | (unsigned char(0x80) >> (index % 8)) :
reinterpret_cast<unsigned char*>(_string)[index / 8] & ((unsigned char(0x80) >> (index % 8)) ^ 0xff);
}
uint32_t get_bit(uint64_t index) const {
return reinterpret_cast<unsigned char*>(_string)[index / 8] & unsigned char(0x80) >> (index % 8) ? 1 : 0;
}
void set_byte(uint64_t index, unsigned char value) {
reinterpret_cast<unsigned char*>(_string)[index] = value;
}
unsigned char get_byte(uint64_t index) {
return reinterpret_cast<unsigned char*>(_string)[index];
}
void trunc(uint64_t s) {
_size_in_bits = s;
}
void reapply(void* byte_string, uint64_t size_in_bits) {
_string = byte_string;
_size_in_bits = size_in_bits;
}
void* string_ptr() { return _string; }
uint64_t size_in_bytes() const {
return _size_in_bits%8 ? _size_in_bits/8 + 1 : _size_in_bits / 8; }
uint64_t size_in_bits() const { return _size_in_bits; }
private:
void* _string = nullptr;
uint64_t _size_in_bits = 0;
};
答案 0 :(得分:0)
您可以创建一维数组并将其用作3维数组,而不是创建“指向指针的指针”数组,将3个索引转换为1。
const size_t SIZE_X = 5;
const size_t SIZE_Y = 5;
const size_t SIZE_Z = 5;
uint32_t *array_1d = new uint32_t[SIZE_X * SIZE_Y * SIZE_Z];
// returns reference to element in 1-d array as if it was 3-d
uint32_t& get_element(size_t x, size_t y, size_t z) {
const size_t ind = x * SIZE_Y * SIZE_Z + y * SIZE_Z + z;
return array_1d[ind];
}
用法:
// set
get_element(0, 3, 2) = 5;
// get
cout << get_element(3, 1, 1);