1

I´m developing a C-MEX SFunction to integrate with simulink. The objective here is to convert an array of ascii codes do double. Before opening matlab, I implemented a test code using Visual Studio and it works just fine. (see below)

#include "stdafx.h"
#include "stdlib.h"
#include <stdio.h>
#include <math.h>
#include <string.h>

int _tmain(int argc, _TCHAR* argv[])
{
    double finalDouble;
    size_t len = 1;
    char* concatenation;
    double character2 = 54; // 6 in ascii
    double character1 = 46; // dot in ascii
    double character0 = 51; // 3 in ascii

    int character2_int = (int)(character2);
    int character1_int = (int)(character1);
    int character0_int = (int)(character0);

    char buffer2[1];
    char buffer1[1];
    char buffer0[1];

    sprintf(buffer2,"%c",character2_int);
    sprintf(buffer1,"%c",character1_int);
    sprintf(buffer0,"%c",character0_int);

    concatenation = (char*)malloc(len+len+len);
    strcpy(concatenation, buffer2); /* copy into the new var */
    strcat(concatenation, buffer1); /* concatenate */
    strcat(concatenation, buffer0); /* concatenate */

    finalDouble = atof(concatenation); // final double must be 6.3

    //y0[0] = finalDouble;
}

After everything was tested in VisualStudio, I copied to SFunction Builder in matlab. It do not crashes, but looks like malloc is not working as expected. The expected output is 6.3 (double), but I get only the last digit 3 (double)

Does anyone know whats happening? Any advices?

enter image description here

guilhermecgs
  • 2,913
  • 11
  • 39
  • 69
  • 3
    Not the whole story but your program is undefined. %c is an invalid format specifier for character2_int in sprintf. – Bathsheba Aug 07 '15 at 14:28
  • humm... not sure if i understood... If you copypaste my code into visual studio it will work. It converts an int to its correct format in ascii – guilhermecgs Aug 07 '15 at 14:30
  • 1
    Just for info, see [Do I cast the result of malloc](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – mihai Aug 07 '15 at 14:32
  • I can not run it OK in Visual Studio. I get memory access errors. – Ander Biguri Aug 07 '15 at 14:42
  • 2
    @guilhermecgs "code works" does not mean "code is correct". If your code exhibits undefined behaviour it may work one day but on on the following day. It may work always in one environnment and never in another one. – Jabberwocky Aug 07 '15 at 14:44
  • @guilhermecgs Your code is quite odd and complicated. What are you trying to achieve exactly? – Jabberwocky Aug 07 '15 at 14:50
  • ok @MichaelWalz .. Thank you for the answers. I said that my code works only because I did not know the meaning of "undefined program". Now I do :-). – guilhermecgs Aug 07 '15 at 16:05
  • @MichaelWalz, what I am trying to do is very simple. I need to receive an array of integers, for example [49 50 51]. Each integer represents an caracther according to ascii table. In this case [49 50 51] -> [1 2 3]. After that, I need to concatenate all arrays positions to get the scalar double 123. – guilhermecgs Aug 07 '15 at 16:08

2 Answers2

2

You are using sprintf on a one byte buffer whereas your buffer should have at least a size of 2. And you don't allocate enough memory with malloc. This leads to undefined behaviour.

Change :

char buffer2[1];
char buffer1[1];
char buffer0[1];
...
concatenation = (char*)malloc(len+len+len);

to

char buffer2[2];
char buffer1[2];
char buffer0[2];
...
concatenation = (char*)malloc(len+len+len+1);

Your code is very odd and complicated for such an easy task. What exactly are you trying to achieve ?

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
1

Your trouble lies in that you're not differentiating between a single character (char) and a string of characters (char[]). From top to bottom:

1) You can assign an ASCII value using single quotation marks:

double character2 = '6';
double character1 = '.';
double character0 = '3';

2) Strings end with a null character, which means the number of bytes required to hold a string of n characters is n+1. Therefore you need at least two bytes to store a single character as a string.

3) sprintf stores a string, meaning it stores a terminating null character after the last char:

sprintf(buffer2,"%c",character2_int); copies a single byte from character2_int to buffer2 and then writes a terminating null character (a decimal 0) to the RAM address &buffer2 + 1.

4) strcpy() and strcat() work on strings, not on single chars. They will continue to copy/concatenate chars untill they find the terminating null character. Again, don't forget to allocate enough space to include the terminating null character.

Michael Kusch
  • 340
  • 4
  • 4