2010-07-26 8 views
3

У меня есть следующая функция, но иногда она терпит неудачу при вызове функции malloc , и я не знаю причины, я думал, что это может быть из-за отсутствия размера кучи, но я контролировал кучу и я понял, что у меня есть достаточно свободного пространства для выделения памяти при таНос не удается, может ли один предложить мне ничегоEXC_BAD_ACCESS При вызове функции 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 (символ * DataBuffer, внутр CommandType) { структура sockaddr_in remoteServerAddr; int tcpSocket; int errorCode; int counter; 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 (плавник транс) { INT RetVal = 0; int ret = 0; int retValCon = 0; char msg [100]; char * voucherId; char * Amount; char * TerminalNo; char * isOnline; char * ReturnedId; TerminalNo = 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); 
} 

}

+3

Отформатируйте свой код для отображения. Отступы с четырьмя пробелами или с помощью кнопки с 101010 помогают в этом. –

+0

Вы уверены, что передаете правильное значение переменной 'numchars'? может ли быть, что кто-то передает эту функцию к униализированной переменной? можете ли вы опубликовать код, вызывающий эту функцию? – Naveen

+0

Btw, при проверке результата из malloc(), лучше всего сравнить с NULL. –

ответ

2

Я не Apple, DEV, но я никогда не видел EXC_BAD_ACCESS на таНос, так что я должен был Google его. Эта запись от Apple technical FAQ выглядит релевантно:

Эта проблема обычно является результатом чрезмерного освобождения объекта. Это может быть очень запутанным, так как отказ имеет тенденцию происходить хорошо после ошибки. Авария может также возникать, когда программа находится глубоко в коде рамки, часто без вашего собственного кода, видимого в стеке.

+0

Я подозреваю, что команды free(), которые я добавил, но я не знаю, почему – arash

-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 

Поэтому, пожалуйста, оценить состояние других переменных в функции или вы можете вставить функцию вызова здесь, чтобы получить лучшие решения.

EDIT: код продолжался после получения информации из комментариев.

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; 
} 

Приведенный выше код работает нормально. Поэтому, пожалуйста, используйте это как ссылку, если вы не можете вставить свою функцию здесь. Я не могу просто догадаться об ошибке.

+0

эта функция не работает для второго вызова, и она запускается в первый раз. после того, как он запускается в первый раз .i call free(), чтобы освободить результат этой функции следующим образом: package = substr (dataBuffer, counter * BUF_SIZE, BUF_SIZE); // bloblob бесплатный (пакет); , но почему malloc не удается? – arash

+0

счетчик * BUF_SIZE, Какое значение здесь? Предположим, вы обходите выделенную память dataBuffer, а затем в функции substr вы делаете недопустимый доступ. Поэтому, пожалуйста, вставьте функцию, которая вызывает этот linepacket = substr (dataBuffer, счетчик * BUF_SIZE, BUF_SIZE); –

+0

функция слишком длинная, но значение BUF_SIZE alwayes равно 512, а счетчик равен 0. Что вы имеете в виду в обход выделенной памяти databuffer? Конечно, это должна быть выделенная память, какой улов? – arash

2

Ваша проблема глубже: EXC_BAD_ACCESS в основном означает, что вы перераспределяете зоны памяти.В отладчике, вы увидите что-то вроде этого

*** таНоса [705]: Ошибка для объекта 0 × 8c5b00: Неправильной контрольной суммы для освобожденного объекта - объект, вероятно, был изменен после освобождения; перерыв в func_name.

Какова ваша платформа? Доступна ли вам Guard Malloc? Если нет, вот что вы можете сделать, помимо изучения вашего исходного кода, конечно:

Напишите оболочку для malloc(), которая будет выделять одну страницу vm для каждого запроса и поместить запрошенный буфер в конец. Таким образом, чтение или запись в прошлом приведет к ошибке шины. Кроме того, когда память свободна() 'd, освободите страницу vm vm, так что всякий раз, когда вы читаете или записываете бесплатный(), вы получаете немедленную ошибку шины. Это займет время, так что будьте готовы!

+0

Я пишу в Eclipse IDE и это программирование устройства POS – arash

+0

Можете ли вы дать мне образец для упомянутой обертки. – arash

+0

Боюсь, я не могу; если вы хотите просмотреть исходный код Guard Malloc или других библиотек, которые следуют одному и тому же методу. Кроме того, поскольку, очевидно, вы не кодируете POS, можете ли вы использовать valgrind или подобные инструменты? –

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

следующее не имеет смысла, что вы пытаетесь сделать? если malloc не удалось, попробуйте еще раз и, прежде всего, почему бесплатно? Вы должны выйти вместо этого и возвращать нулевое

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

Я думаю, что ошибка где-то еще, может быть, вы должны проверить в-параметров, убедитесь, что pstr не NULL и NUMCHARS> 0

+0

ошибка происходит прямо в строке первого malloc, мне интересно, что эта функция работает хорошо в первый раз – arash

0

Вы, вероятно, поврежден ваш malloc где-то раньше в коде, но проблема не появляется до тех пор, пока вы не назовете malloc или не свободны - вы должны запустить код под valgrind или аналогично сужать основную причину.

+0

кажется, что вы правы, но как я могу выделите новый блок памяти для использования или что я могу сделать, если куча повреждена – arash

+0

@arash: вам нужно ** отлаживать ** причину повреждения кучи malloc - ваш код не будет стабильным до тех пор, пока вы это сделаете - запустите код под ** valgrind **, и это должно привести вас к проблеме, которую вы затем можете исправить, и malloc/free затем будет вести себя так, как ожидалось, еще раз. –

Смежные вопросы