tags:

views:

80

answers:

5

hi I have the following function but sometimes it fails on the malloc function call and I don't know the reason,I thought that it may be due to lack of heap size but I have monitored the heap and I understood that I have enough space available for memory allocation when malloc fails ,can any one suggest anything to me

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 counter; int PacketsToSend; int32 ret; char msgbuf[16]; char *packet; 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 * Amount; char * TerminalNo; char * isOnline; char * ReturnedId; TerminalNo=malloc(12); voucherId=malloc(4); Amount=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);
}

}

+1  A: 

I'm no Apple dev, but I've never seen EXC_BAD_ACCESS on malloc so I had to Google it. This entry from the Apple technical FAQ looks relevant:

This kind of problem is usually the result of over-releasing an object. It can be very confusing, since the failure tends to occur well after the mistake is made. The crash can also occur while the program is deep in framework code, often with none of your own code visible in the stack.

Christoffer
i am suspect to the free() commands that i have added but i don't know why
arash
A: 

This mite help clear things:

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

So please evaluate the state of other variables in the function or you can paste the calling function here to get better solutions.

EDIT: code continued after getting information from the comments.

NULL check avoided intentionally.

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

The above code works fine. So please use this as reference if you cant paste your function here. I can't just guess the error.

Praveen S
this function fails for the second call, and it runs for the first time. after it runs for the first time .i call free() function to release the result of this function like this:packet= substr(dataBuffer, counter*BUF_SIZE, BUF_SIZE);//bloblobfree(packet) ;but why malloc fails?
arash
counter*BUF_SIZE, Whats the value here? Suppose you bypass the allocated memory of dataBuffer, then in the function substr you are doing a invalid access. So please paste the function which calls this linepacket= substr(dataBuffer, counter*BUF_SIZE, BUF_SIZE);
Praveen S
the function is too long,but the value of BUF_SIZE alwayes is equal to 512 and counter is equal to 0.what do you mean bypassing the allocated memory of databuffer?ofcourse it must be allocated memory,what's the catch?
arash
So start is always 0. Whats the value of numchars? How much memory is allocated to dataBuffer? Also you can trim the big function to paste just relevant parts.
Praveen S
databuffer is defined like this: char dataBuffer[100];well numchars has the value of BUF_SIZE as you can see in this line:packet= substr(dataBuffer, counter*BUF_SIZE, BUF_SIZE); I mean numchars is equal to 512.
arash
What is value of counter? I think you will be exceeding the size of dataBuffer in second call as pstr+start will be greater than 512.
Praveen S
as I told before counter is equal to zero.but databuffer is defined like this :char dataBuffer[100]
arash
Please check my edit and reply.
Praveen S
My calling function has a slight diffrence:in your for loop you need to change the value of buff each time to diffrent values with strcpy and strcat functions.
arash
You mean you do a strcpy(buff,"xyz") etc etc and then run the loop?Ok you do that slight change and paste here and lets take it ahead from there.
Praveen S
consider this:strcpy(buff, "<Req_fin>");strcat(buff, "1");strcat(buff, "<EOF>");for example I pass it when i==1;and when i==2 i pass diffrrent thing in this way:memset(buff, 0, sizeof(msg));strcpy(buff, "<Req_fin_c>");strcat(buff, "<EOF>");so each time that substr is called the buff has a diffrent value and before assigning new value i use memset function.
arash
Why do you use sizeof(msg) instead of sizeof(buff)? Please check my edit now. It works fine now too.
Praveen S
it looks simailar to my code,but my code still fails and I don't get it.is there anyway to undrestand when the malloc will fail to prevent it?maybe i could send my code if you gave me your email.
arash
Paste it here. I think it wil fetch you optimal solutions. If its big, crop it.
Praveen S
please see my edited code
arash
` 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>");`Have you checked if combined values of these exceeds 100 or not?Next, in your while loop, where are you freeing packet?
Praveen S
+1  A: 

Your problem is deeper: EXC_BAD_ACCESS basically means that you are over-freeing zones of memory. In a debugger, you'd see something like this

*** malloc[705]: error for object 0×8c5b00: Incorrect checksum for freed object - object was probably modified after being freed; break at func_name.

What's your platform? Is Guard Malloc available to you? If not, here's what you can do, besides scrutinizing your source code, of course:

Write a wrapper for malloc() which will allocate a single vm page for every request and place the requested buffer at its end. That way, reads or writes past it will cause a bus error. Also, when memory is free()'d, deallocate your vm page(s), so that whenever you read or write to a free()'d are you get an immediate bus error. It's going to take a loooong time, so be prepared!

Michael Foukarakis
I am writing in eclipse IDE and it is POS device programming
arash
can you give me a sample for the mentioned wrapper.
arash
I'm afraid I can't; if you wish you can view the source code for Guard Malloc or other libraries that follow the same method. Also, since obviously you're not coding at the POS, could you use valgrind or similar tools?
Michael Foukarakis
I am coding in Windows platform it seems the valgrind only support macOS and linux
arash
+1  A: 
char *substr(const char *pstr, int start, int numchars)
{
 char *pnew;
 pnew=malloc(numchars+1);  //this line fails

the following makes no sense, what is it you are trying to do? if malloc failed why try again and above all why free? You should exit instead and return null

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

I think the error is somewhere else, maybe you should check the in-parameters, make sure pstr is not NULL and numchars > 0

Anders K.
the error happens right in the line of first malloc,I am wondering that this function works well for the first time
arash
A: 

You probably corrupted your malloc heap somewhere earlier in the code but the problem does not show up until you call malloc or free - you should run the code under valgrind or similar to narrow down the root cause.

Paul R
it seems you are right but how can I allocate a new memory block to use or what can i do if heap is coruppted
arash
@arash: you need to **debug** the cause of the malloc heap corruption - your code will not be stable until you do this - run the code under **valgrind** and it should take you straight to the problem, which you can then fix, and malloc/free should then behave as expected once again.
Paul R