1
votes

There is a requirement where a client has to format a received stream of data separated by semicolon ";" and pass on the data to Matlab environment via mex function. I had created .dll to do the pre processing in C (Visual Studio 2010 and 2013) .

The .dll generated with Visual Studio 2013(ToolSet vs120) gives a segmentation fault and .dll generated with Visual Studio 2010(ToolSet vs100) works fine.

The same .c file is used for .dll generation.

On commenting the free(y_1) in the mex function the .dll with Visual Studio 2013 works.

I am passing a 2D pointer from the .dll to mex, this is where its throwing an error. I have added the code for the .dll and the corresponding mex function.

/*Decleration*/
typedef struct twoDArray {
    char **new_line ;
    int noOfLines ;
}TWODARRAY;
 TWODARRAY *y_1;
static TWODARRAY x_1;
 /*********************************************************/
/*Mex function*/

       if (!strcmp(fct_name, "GetSignal")) {
       ProcAdd2 = (MYPROC2)GetProcAddress(hinstDLL, "getAvailableSignals");
       lineCount = 0;
       if (-1 == sock_no) {
            mexErrMsgIdAndTxt("MATLAB:Client:conversionFailed","Connection to server not established.");
            }
       else {
            y_1 = (TWODARRAY *)malloc(sizeof *y_1);
            y_1 = (ProcAdd2)(sock_no);
            x_1.new_line = y_1->new_line;
            x_1.noOfLines = y_1->noOfLines;
            free(y_1);
            plhs[0]=mxCreateCellMatrix(x_1.noOfLines, 1);
            for (i=0;i<x_1.noOfLines;i++) {
            /* insert the line into the output array... */
                mxSetCell(plhs[0],i,mxCreateString(x_1.new_line[i]));
                }
            while(lineCount<x_1.noOfLines) {
                //printf("\n%s\n",  x_1.new_line[lineCount]);
                lineCount++;
                }

            }   
        } 
      /*********************************************************/
    /* .Dll Function .C file*/
    TWODARRAY *  GetSignalArray(char *received_str) {
    TWODARRAY *z = (TWODARRAY *)malloc(sizeof *z);
    z->new_line = NULL;
    z->noOfLines = N_NO_OF_LINES;
    char* str_tok;
    int lineCount = 0;
    z->new_line = (char **)malloc(sizeof(char*) * N_NO_OF_LINES);/* Get the address of the token */
    str_tok = strtok(received_str, ";");

    /* Search for the token anf arrange the stream of strings into 2D character array */
    while (str_tok != NULL) {
        if (lineCount >= z->noOfLines) {
            z->new_line =  (char **)realloc(z->new_line, (sizeof(char*)*(z->noOfLines+N_NO_OF_LINES)));
            z->noOfLines += N_NO_OF_LINES;
            }
        z->new_line[lineCount] = _strdup(str_tok);
        //printf("\nZ 2D Array\n%s\n",  z->new_line[lineCount]);
        lineCount++;
        str_tok = strtok(NULL, ";");
        }
        z->noOfLines = lineCount;
        return(z);
}


DECLDIR TWODARRAY * getAvailableSignals(SOCKET ConnectSocket)
    {
        char *sendbuf = "0000GetAvailableSignals";
        static char *received_stream;
        TWODARRAY *y = (TWODARRAY *)malloc(sizeof *y);
        int lineCount = 0;

        if (ConnectSocket == INVALID_SOCKET) {
            printf("socket failed with error: %ld\n", WSAGetLastError());
            return (y);
        }
        /* Function to send a request and receive a response from server */
        received_stream=send_data(ConnectSocket,sendbuf);

        /* Function to generate 2D array from selected signal stream */
        y = GetSignalArray(received_stream);
        return (y);
    }

Reason for crash after using Visual Studio 2013 .dll

2
TWODARRAY *z = (TWODARRAY *)malloc(sizeof(TWODARRAY)); 09481247 mov edi,dword ptr ds:[9484090h]Vinayak Killedar

2 Answers

0
votes

I don't think the fact that it crashes on a specific version of visual-studio is important to your problem. Your code seems to be leaking memory. You allocate memory twice:

TWODARRAY *z = (TWODARRAY *)malloc(sizeof *z);
...
TWODARRAY *y = (TWODARRAY *)malloc(sizeof *y);

but you free it only once. The pointer to allocated memory is overwritten by:

y = GetSignalArray(received_stream);

Also, where is the memory allocated to the new_line field being freed?

0
votes

Assembly Code generated via 2013

TWODARRAY *z = (TWODARRAY *)malloc(sizeof(TWODARRAY));
09481247  mov         edi,dword ptr ds:[9484090h]}

Assembly Code generated via 2010

TWODARRAY *z = (TWODARRAY *)malloc(sizeof *z);
09091239  mov         edi,dword ptr [__imp__malloc (90940A4h)]  

Is the memory allocation different incase of 2010 and 2013?

In 2013 the memory is allocated in Data Segment and in 2010 its Heap Is there any impact due to this on the segmentation fault?