首页 文章

EXC_BAD_ACCESS调用malloc函数时

提问于
浏览
3

我有以下功能,但有时它在malloc函数调用失败,我不知道原因,我认为这可能是由于缺少堆大小但我已经监控堆,我知道我有足够的空间可用对于malloc失败时的内存分配,任何人都可以向我提出任何建议

char *substr(const char *pstr, int start, int numchars)
{
 char *pnew;
 pnew=malloc(numchars+1);  //this line fails
 if (pnew==0)
 {
  free(pnew);
  pnew=malloc(numchars+1);
 }


 strncpy(pnew, pstr + start, numchars);
 pnew[numchars] = '\0';
 return pnew;

}

int32 SendData(char * dataBuffer,int CommandType){struct sockaddr_in remoteServerAddr; int tcpSocket; int errorCode;柜台; int PacketsToSend; int32 ret; char msgbuf [16]; char *包; char * cmdIRes; char RecPacket [BUF_SIZE]; div_t divresult;

counter = 0;
/* Specify struct sock address */
memset(&remoteServerAddr, 0, sizeof(remoteServerAddr));
remoteServerAddr.sin_len = sizeof(remoteServerAddr);
remoteServerAddr.sin_family = AF_INET;
remoteServerAddr.sin_port = htons(11000); // Net byte order required
remoteServerAddr.sin_addr.s_addr = inet_addr("10.252.85.26");

/* Create an TCP socket */
tcpSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (tcpSocket != -1)
{
    /* Connect to server */
    errorCode = connect(tcpSocket, (struct sockaddr*) &remoteServerAddr,
            sizeof(remoteServerAddr));
    if (errorCode == -1)
    {
        /* Connection failed */
        errorCode = socketerror();
        sprintf(msgbuf, "Error %d", errorCode);
        displayMsg("connect:", "Failed!!!", msgbuf, NULL, 0x0100FFFF);
    }
    else
    {
        /* Send packets */
        divresult=div(sizeof(dataBuffer), BUF_SIZE);
        PacketsToSend=divresult.quot;
        if (divresult.rem>0)
        {
            PacketsToSend=PacketsToSend+1;
        }

        while (counter < PacketsToSend)
        {

            packet= substr(dataBuffer, counter*BUF_SIZE, BUF_SIZE);
            errorCode = send(tcpSocket, packet,strlen(packet) , 0);
            if (errorCode == -1)
            {
                errorCode = socketerror();
                sprintf(msgbuf, "Error %d", errorCode);
                displayMsg("send:", "Failed!!!", msgbuf, NULL, 0x0100FFFF);
                break;
            }
            counter++;
        }
        memset(RecPacket, 0, BUF_SIZE);
        errorCode = recv(tcpSocket, RecPacket, BUF_SIZE,0);
        if (errorCode == -1)
        {
            errorCode = socketerror();
        }

        switch (CommandType)
        {
        case CommandType_SendOneTrans:
        case CommandType_SendOfflineData:
            cmdIRes=substr(RecPacket, 14, 10);
            ret= atoi(cmdIRes);
            break;

        case CommandType_TransConfirm:
            cmdIRes=substr(RecPacket, 11, 2);
            if (strcmp(cmdIRes, "ok")==0)
            {
                ret= 1;
            }
            else
            {
                ret= 0;
            }
            break;
        case CommandType_VoucherList:
            SaveVoucherList(RecPacket);
            ret= 1;
            break;

        case CommandType_Identify:
            cmdIRes= substr(RecPacket, 7, 2);
            if (strcmp(cmdIRes, "ok")==0)
            {
                ret=1;
            }
            else
            {
                ret= 0;
            }
            break;

        default:
            break;
        }



    }
    /* Close the socket */
    close(tcpSocket);
    free(RecPacket);
    free(cmdIRes);
    free(packet);
    free(msgbuf);
    return ret;
}
else
{
    errorCode = socketerror();
    sprintf(msgbuf, "Error %d", errorCode);
    displayMsg("socket:", "Failed!!!", msgbuf, NULL, 0x0100FFFF);
}
return (errorCode);

}

uint32 SendOneTrans(fin trans){int retVal = 0; int ret = 0; int retValCon = 0; char msg [100]; char * voucherId; char *金额; char * TerminalNo; char * isOnline; char * ReturnedId;终端不是= malloc的(12); voucherId = malloc的(4);量= malloc的(7); isOnline = malloc的(1); ReturnedId = malloc的(3);

memset(TerminalNo, 0, sizeof(TerminalNo));
strcpy(TerminalNo, (char *)getTerminalNo());

memset(msg, 0, sizeof(msg));
if (trans.success==0)
{

    memset(msg, 0, sizeof(msg));
    memset(voucherId, 0, sizeof(voucherId));
    sprintf(voucherId, "%d", trans.voucherId);
    memset(Amount, 0, sizeof(Amount));
    sprintf(Amount, "%d", trans.Amount);

    memset(isOnline, 0, sizeof(isOnline));
    sprintf(isOnline, "%d", trans.isOnline);

    strcpy(msg, "<Req_fin>");
    strcat(msg, TerminalNo);
    strcat(msg, ",");
    strcat(msg, voucherId);
    strcat(msg, ",");
    strcat(msg, trans.cardNo);
    strcat(msg, ",");
    strcat(msg, Amount);
    strcat(msg, ",");
    strcat(msg, trans.dateOf);
    strcat(msg, ",");
    strcat(msg, trans.TimeOf);
    strcat(msg, ",1");
    strcat(msg, "<EOF>");
    retVal= SendData(msg, CommandType_SendOneTrans);

    if (retVal>=1)
    {
        sprintf(ReturnedId, "%i", retVal);
        memset(msg, 0, sizeof(msg));
        strcpy(msg, "<Req_fin_c>");
        strcat(msg, TerminalNo);
        strcat(msg, ",");

        strcat(msg, ReturnedId);
        strcat(msg, "<EOF>");
        trans.success=1;
        retValCon= SendData(msg, CommandType_TransConfirm);
        if (retValCon!=0)
        {
            trans.success=1;
            ret=1;
        }
    }

    free(msg);
    free(TerminalNo);
    free(Amount);
    free(voucherId);
    return ret;
    //free(ReturnedId);
}

}

5 回答

  • 2

    我没有在malloc上看过EXC_BAD_ACCESS,所以我不得不谷歌 . 来自Apple technical FAQ的此条目看起来相关:

    这种问题通常是过度释放对象的结果 . It can be very confusing, since the failure tends to occur well after the mistake is made. 当程序深入框架代码时,也可能发生崩溃,通常在堆栈中没有自己的代码可见 .

  • 2

    您的问题更深入:EXC_BAD_ACCESS基本上意味着您过度释放内存区域 . 在调试器中,您会看到类似这样的内容

    *** malloc [705]:对象0×8c5b00的错误:释放对象的校验和不正确 - 对象可能在被释放后被修改;在func_name处中断 .

    你的平台是什么? Guard Malloc可供您使用吗?如果没有,除了仔细检查您的源代码之外,这是您可以做的事情,当然:

    为malloc()编写一个包装器,它将为每个请求分配一个vm页面,并将请求的缓冲区放在其末尾 . 这样,读取或写入它将导致总线错误 . 此外,当内存空闲()时,请释放您的虚拟机页面,以便每当您读取或写入空闲()时,您都会立即收到总线错误 . 这需要花费很多时间,所以要做好准备!

  • 0
    char *substr(const char *pstr, int start, int numchars)
    {
     char *pnew;
     pnew=malloc(numchars+1);  //this line fails
    

    以下没有意义,你想做什么?如果malloc失败了为什么再试一次,最重要的是为什么免费?您应该退出而返回null

    if (pnew==0)   
     {
      free(pnew);
      pnew=malloc(numchars+1);
     }
    

    我认为错误是在其他地方,也许你应该检查in-parameters,确保pstr不是NULL和numchars> 0

  • -1

    您可能在代码中较早的某处损坏了malloc堆,但问题在您调用malloc或free之前不会显示 - 您应该在valgrind或类似的下运行代码以缩小根本原因 .

  • 1

    这种螨有助于清除事物:

    You will get EXC_BAD_ACCESS in 3 cases:
    
       1. An object is not initialized
       2. An object is already released
       3. Something else that is not very likely to happen
    

    因此,请评估函数中其他变量的状态,或者您可以在此处粘贴调用函数以获得更好的解决方案 .

    编辑:从评论中获取信息后代码继续 .

    故意避免NULL检查 .

    char a[][100] = {"<Req_fin>1","<Req_fin>1","<Req_fin>1<EOF>","<Req_fin>1<EOF>","<Req_fin>1","<Req_fin>1<EOF>","<Req_fin>1<EOF>","<Req_fin>1<EOF>","<Req_fin>1","<Req_fin>1<EOF>"};
    char *b= "<EOF>";
    char *substr(char *buff,int start,int bytes)
    {
    char *ptr;
    
    ptr = malloc(bytes+1);
    strncpy(ptr,buff+start,bytes);
    ptr[bytes]='\0';
    return ptr;
    }
    int main()
    {
    char buff[100];
    int i;
    char *ptr;
    strcpy(buff,"Abcdef");
    for(i=0;i<10;i++)
    {
    ptr = substr(buff,0,512);
    printf("String is %s \n",ptr);
    memset(buff,0,sizeof(buff));
    strcpy(buff,a[i]);
    strcat(buff,b);
     free(ptr);
    }
    return 0;
    }
    

    上面的代码工作正常 . 因此,如果您无法在此处粘贴功能,请将此作为参考 . 我不能只猜错误 .

相关问题