引发了异常: 写入访问权限冲突。

时间:2022-06-14 15:19:51
删除无关代码后,代码如下
struct NODE {
int data ;
int next ;
} ;

class myAllocator ;

class myBuffer {
private:
friend myAllocator ;
NODE *mBuffer ;
int mLength ;

public:
inline explicit myBuffer (int len) {
_DEBUG_ASSERT_ (len >= 0) ;
mBuffer = len > 0 ? new NODE[len] : NULL ;
mLength = len ;
}

inline ~myBuffer () {
if (mBuffer != NULL) {
delete[] mBuffer ;
mBuffer = NULL ;
mLength = 0 ;
}
}

inline myBuffer (myBuffer &&right) {
mBuffer = right.mBuffer ;
mLength = right.mLength ;
right.mBuffer = NULL ;
right.mLength = 0 ;
}

inline myBuffer &operator= (myBuffer &&right) {
if (this == &right)
return *this ;
this->~myBuffer () ;
new (this) myBuffer (std::move (right)) ;
return *this ;
}

inline NODE &operator[] (int index) {
_DEBUG_ASSERT_ ((index >= 0 && index < mLength) || mLength == 0) ;
return mBuffer[index] ;
}

inline const NODE &operator[] (int index) const {
_DEBUG_ASSERT_ ((index >= 0 && index < mLength) || mLength == 0) ;
return mBuffer[index] ;
}
} ;

class myAllocator {
private:
myBuffer mAlloc ;
int mFree ;

public:
inline explicit myAllocator (int len) :mAlloc (len) {
update (0 ,-1) ;
}

inline int &operator[] (int index) {
_DEBUG_ASSERT_ (mAlloc[index].next == -2) ;
return mAlloc[index].data ;
}

inline int alloc (int arg) {
resize () ;
int ret = mFree ;
mAlloc[ret].data = arg ;
mFree = mAlloc[ret].next ;
mAlloc[ret].next = -2 ;
return ret ;
}

private:
inline void resize () {
if (mFree != -1)
return ;
myAllocator ret (mAlloc.mLength + 1024) ;
for (int i = 0 ; i < mAlloc.mLength ; i++)
ret.mAlloc[i] = mAlloc[i] ;
ret.update (mAlloc.mLength ,mFree) ;
mAlloc = std::move (ret.mAlloc) ;
mFree = ret.mFree ;
}

inline void update (int ib ,int jb) {
mFree = jb ;
if (ib >= mAlloc.mLength)
return ;
for (int i = ib ; i < mAlloc.mLength - 1 ; i++)
mAlloc[i].next = i + 1 ;
mAlloc[mAlloc.mLength - 1].next = mFree ;
mFree = ib ;
}
} ;

int main () {
myAllocator al2 (0) ;
int a2 = -1 ;
int b2 = -1 ;
while (TRUE) {
b2 = (b2 != -1 ? al2[b2] : a2) = al2.alloc (-1) ;
}
return 0 ;
}

10 个解决方案

#1


引发了异常: 写入访问权限冲突。

#2


main函数这段代码想用myAllocator建立一个链表,a2为头,b2为尾,-1表示空元素
然而会报错,所有断言均未触发,抛出的也不是c++异常(捕获不了)
不使用连续的=的时候就没有这个问题,然而我想知道这个问题的原因

#3


VS 问题.......

#4


al2.alloc (-1) ;
===============
不能传负值呀!

#5


引用 3 楼 GKatHere 的回复:
VS 问题.......

还真是,g++编译的就没问题,能从反汇编代码分析一下原因吗?

#6


引用 4 楼 yshuise 的回复:
al2.alloc (-1) ;
===============
不能传负值呀!

alloc是新建节点
我把节点数据域删了
所以参数只剩下链表节点的next
这next是存在分配器的data里的
因为是尾插,所以指向-1

#7


 _DEBUG_ASSERT_ (len >= 0) ;
---------------------------------------------------------
这玩意儿是调试起作用,len不能小于0的

#8


引用 7 楼 yshuise 的回复:
 _DEBUG_ASSERT_ (len >= 0) ;
---------------------------------------------------------
这玩意儿是调试起作用,len不能小于0的

[code=c][/#include <type_traits>
#include <new>

#define _UNW_IMPL_(...) __VA_ARGS__
#define _UNW_(...) _UNW_IMPL_(__VA_ARGS__)
#define _DEBUG_ASSERT_(...) do { if (!(_UNW_ (__VA_ARGS__))) __debugbreak () ; } while (false)

#define FALSE false
#define TRUE true
#define NULL nullptrcode]
你运行一下,没有一个断言是被触发的

#9


崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处, 看不懂时双击下一行,直到能看懂为止

#10


引用 9 楼 zhao4zhong1 的回复:
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处, 看不懂时双击下一行,直到能看懂为止

		b2 = (b2 != -1 ? al2[b2] : a2) = al2.alloc (-1) ;
000000013F568939  cmp         dword ptr [b2],0FFFFFFFFh  
000000013F56893D  je          main+84h (013F568954h)  
000000013F56893F  mov         edx,dword ptr [b2]  
000000013F568942  lea         rcx,[al2]  
000000013F568946  call        myAllocator::operator[] (013F56100Fh)  
000000013F56894B  mov         qword ptr [rbp+188h],rax  
000000013F568952  jmp         main+8Fh (013F56895Fh)  
000000013F568954  lea         rax,[a2]  
000000013F568958  mov         qword ptr [rbp+188h],rax  
000000013F56895F  mov         rax,qword ptr [rbp+188h]  
000000013F568966  mov         qword ptr [rbp+138h],rax  
000000013F56896D  mov         edx,0FFFFFFFFh  
000000013F568972  lea         rcx,[al2]  
000000013F568976  call        myAllocator::alloc (013F56130Ch)  
000000013F56897B  mov         rcx,qword ptr [rbp+138h]  
中断-》 000000013F568982  mov         dword ptr [rcx],eax  
000000013F568984  mov         rax,qword ptr [rbp+138h]  
000000013F56898B  mov         eax,dword ptr [rax]  
000000013F56898D  mov         dword ptr [b2],eax  

监视里看到的变量值都是正确的
然而就中断了,不是很清楚汇编能分析一下什么问题吗
rax 71680 unsigned __int64
rbx 0 unsigned __int64
rcx 5882024 unsigned __int64
rdx 71680 unsigned __int64
rbp 2620336 unsigned __int64

#1


引发了异常: 写入访问权限冲突。

#2


main函数这段代码想用myAllocator建立一个链表,a2为头,b2为尾,-1表示空元素
然而会报错,所有断言均未触发,抛出的也不是c++异常(捕获不了)
不使用连续的=的时候就没有这个问题,然而我想知道这个问题的原因

#3


VS 问题.......

#4


al2.alloc (-1) ;
===============
不能传负值呀!

#5


引用 3 楼 GKatHere 的回复:
VS 问题.......

还真是,g++编译的就没问题,能从反汇编代码分析一下原因吗?

#6


引用 4 楼 yshuise 的回复:
al2.alloc (-1) ;
===============
不能传负值呀!

alloc是新建节点
我把节点数据域删了
所以参数只剩下链表节点的next
这next是存在分配器的data里的
因为是尾插,所以指向-1

#7


 _DEBUG_ASSERT_ (len >= 0) ;
---------------------------------------------------------
这玩意儿是调试起作用,len不能小于0的

#8


引用 7 楼 yshuise 的回复:
 _DEBUG_ASSERT_ (len >= 0) ;
---------------------------------------------------------
这玩意儿是调试起作用,len不能小于0的

[code=c][/#include <type_traits>
#include <new>

#define _UNW_IMPL_(...) __VA_ARGS__
#define _UNW_(...) _UNW_IMPL_(__VA_ARGS__)
#define _DEBUG_ASSERT_(...) do { if (!(_UNW_ (__VA_ARGS__))) __debugbreak () ; } while (false)

#define FALSE false
#define TRUE true
#define NULL nullptrcode]
你运行一下,没有一个断言是被触发的

#9


崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处, 看不懂时双击下一行,直到能看懂为止

#10


引用 9 楼 zhao4zhong1 的回复:
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处, 看不懂时双击下一行,直到能看懂为止

		b2 = (b2 != -1 ? al2[b2] : a2) = al2.alloc (-1) ;
000000013F568939  cmp         dword ptr [b2],0FFFFFFFFh  
000000013F56893D  je          main+84h (013F568954h)  
000000013F56893F  mov         edx,dword ptr [b2]  
000000013F568942  lea         rcx,[al2]  
000000013F568946  call        myAllocator::operator[] (013F56100Fh)  
000000013F56894B  mov         qword ptr [rbp+188h],rax  
000000013F568952  jmp         main+8Fh (013F56895Fh)  
000000013F568954  lea         rax,[a2]  
000000013F568958  mov         qword ptr [rbp+188h],rax  
000000013F56895F  mov         rax,qword ptr [rbp+188h]  
000000013F568966  mov         qword ptr [rbp+138h],rax  
000000013F56896D  mov         edx,0FFFFFFFFh  
000000013F568972  lea         rcx,[al2]  
000000013F568976  call        myAllocator::alloc (013F56130Ch)  
000000013F56897B  mov         rcx,qword ptr [rbp+138h]  
中断-》 000000013F568982  mov         dword ptr [rcx],eax  
000000013F568984  mov         rax,qword ptr [rbp+138h]  
000000013F56898B  mov         eax,dword ptr [rax]  
000000013F56898D  mov         dword ptr [b2],eax  

监视里看到的变量值都是正确的
然而就中断了,不是很清楚汇编能分析一下什么问题吗
rax 71680 unsigned __int64
rbx 0 unsigned __int64
rcx 5882024 unsigned __int64
rdx 71680 unsigned __int64
rbp 2620336 unsigned __int64