内存分配问题
我正在编写一个动态分配内存的Windows 服务。我尝试了c++的new运算符和C的malloc。它们返回(可能有效)指针,但是当我尝试取消引用它时,程序崩溃,Windows 说:
“0x77c478ac”处的指令 引用的内存位于“0x00cb9001”。这 内存无法“读取”。
顺便说一句,我猜指针是有效的,因为引用的内存不为空(0x00cb9001)。
编辑:这是代码
/* This is a thread procedure that is
called when connection arrives
and its purpose is to serve as a
regular expression server.
*/
void threadProc(LPVOID *ptr){
SOCKET accSock = (SOCKET) *ptr;
void * foundPtr;
int recvdBytes;
char * literalPtr;
u_long iMode = 0;
literalPtr = new char [4096]; //this may cause the problem
//We allocate 4kb but in fact the first 2 kbs will be for
//for the literal string, the next 2 kb are for the result
//that must be returned
ioctlsocket(accSock, FIONBIO, &iMode); //the "parent" socket was nonblocking
if(literalPtr){
recvdBytes = recv(accSock, (literalPtr+1), 2048, 0); //BTW, recv returns -1
foundPtr = regexp_cmp(literalPtr, fBuffer, 0); //program crashes when calling this function
if(!foundPtr){
*(literalPtr+2048) = (int) 0;
send(accSock, (char *) (literalPtr+2048), 4, 0); //sending 4 NULLs
}
else {
send(accSock, (char *) (literalPtr+2048), 2048, 0);
}
shutdown (accSock, 0);
delete[] literalPtr;
return;
}
I'm writing a Windows Service that allocates memory dynamically. I tried both c++'s new operator and C's malloc. They return (probably valid) pointer but when I try to dereference it the program crashes with Windows saying:
The instruction at "0x77c478ac"
referenced memory at "0x00cb9001". The
memory could not be "read".
BTW I guess the pointer is valid because the referenced memory is not NULL (0x00cb9001).
EDIT: Here is the code
/* This is a thread procedure that is
called when connection arrives
and its purpose is to serve as a
regular expression server.
*/
void threadProc(LPVOID *ptr){
SOCKET accSock = (SOCKET) *ptr;
void * foundPtr;
int recvdBytes;
char * literalPtr;
u_long iMode = 0;
literalPtr = new char [4096]; //this may cause the problem
//We allocate 4kb but in fact the first 2 kbs will be for
//for the literal string, the next 2 kb are for the result
//that must be returned
ioctlsocket(accSock, FIONBIO, &iMode); //the "parent" socket was nonblocking
if(literalPtr){
recvdBytes = recv(accSock, (literalPtr+1), 2048, 0); //BTW, recv returns -1
foundPtr = regexp_cmp(literalPtr, fBuffer, 0); //program crashes when calling this function
if(!foundPtr){
*(literalPtr+2048) = (int) 0;
send(accSock, (char *) (literalPtr+2048), 4, 0); //sending 4 NULLs
}
else {
send(accSock, (char *) (literalPtr+2048), 2048, 0);
}
shutdown (accSock, 0);
delete[] literalPtr;
return;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这很有趣,你的代码中已经注释了答案。 recv 返回 -1,表明没有读取任何字节并且存在错误(为什么不检查 errno 并查看问题是什么?),然后无论如何在未初始化的缓冲区上调用 regexp_cmp。难怪会崩溃。
第二点,您的代码过于复杂。例如,缓冲区大小是固定的。何必费心去换新呢?您可以将缓冲区保留在堆栈上。为什么要为两个不同的目的共享同一个缓冲区?只需分配2个缓冲区;一个用于发送,另一个用于接收。那么您就不需要处理可能有问题的指针数学。
It's pretty funny, you have the answer commented in your code. recv returns -1, indicating that no bytes were read and there is an error, (why not check errno and see what the problem is?) and then you call regexp_cmp anyway on an uninitialized buffer. No wonder it crashes.
As a second point, your code it overly complex. For example, the buffer size is fixed. Why bother newing it? You can keep the buffer on the stack. Why share the same buffer for two different purposes? Just allocate 2 buffers; one for send and the other for recv. Then you don't need to deal with possibly problematic pointer math.
我假设 regexp_cmp(literalPt... 将 lineralPt 视为字符串:该字符串不是以 null 结尾的(我看不到任何终止该字符串的代码),因此该函数只是超出了该缓冲区寻找永远不会出现的“\0”...
I'm assuming
regexp_cmp(literalPt...
treats lineralPt as a string: that string is not null terminated ( I can't see any code effort to terminate that string ) so the function simply overrun that buffer looking for the '\0' that never comes...