在 Function 中使用 malloc 时出错
Error using malloc inside SFunction
我正在开发 C-MEX SFunction 以与 simulink 集成。这里的objective是将ascii码数组做double转换。在打开 matlab 之前,我使用 Visual Studio 实现了一个测试代码,并且 它工作得很好。
(见下文)
#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;
}
在VisualStudio中测试完所有内容后,我将其复制到matlab中的SFunction Builder中。它不会崩溃,但看起来 malloc 没有按预期工作。
预期输出是 6.3 (double),但我只得到最后一个数字 3 (double)
有人知道发生了什么事吗?有什么建议吗?
您在单字节缓冲区上使用 sprintf
,而您的缓冲区大小至少应为 2。并且您没有为 malloc
分配足够的内存。这会导致未定义的行为。
变化:
char buffer2[1];
char buffer1[1];
char buffer0[1];
...
concatenation = (char*)malloc(len+len+len);
到
char buffer2[2];
char buffer1[2];
char buffer0[2];
...
concatenation = (char*)malloc(len+len+len+1);
对于如此简单的任务,您的代码非常奇怪和复杂。你到底想达到什么目的
?
您的问题在于您没有区分单个字符 (char
) 和一串字符 (char[]
)。
从上到下:
1) 您可以使用单引号分配一个 ASCII 值:
double character2 = '6';
double character1 = '.';
double character0 = '3';
2) 字符串以空字符结尾,这意味着容纳n个字符的字符串所需的字节数为n+1。因此,您至少需要两个字节才能将单个字符存储为字符串。
3) sprintf
存储一个字符串,这意味着它在最后一个字符之后存储一个终止空字符:
sprintf(buffer2,"%c",character2_int);
将单个字节从 character2_int
复制到 buffer2
,然后将终止空字符(十进制 0)写入 RAM 地址 &buffer2 + 1
.
4) strcpy()
和 strcat()
处理字符串,而不是单个 chars
。他们将继续 copy/concatenate chars
直到找到终止空字符。同样,不要忘记分配足够的 space 来包含终止空字符。
我正在开发 C-MEX SFunction 以与 simulink 集成。这里的objective是将ascii码数组做double转换。在打开 matlab 之前,我使用 Visual Studio 实现了一个测试代码,并且 它工作得很好。 (见下文)
#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;
}
在VisualStudio中测试完所有内容后,我将其复制到matlab中的SFunction Builder中。它不会崩溃,但看起来 malloc 没有按预期工作。 预期输出是 6.3 (double),但我只得到最后一个数字 3 (double)
有人知道发生了什么事吗?有什么建议吗?
您在单字节缓冲区上使用 sprintf
,而您的缓冲区大小至少应为 2。并且您没有为 malloc
分配足够的内存。这会导致未定义的行为。
变化:
char buffer2[1];
char buffer1[1];
char buffer0[1];
...
concatenation = (char*)malloc(len+len+len);
到
char buffer2[2];
char buffer1[2];
char buffer0[2];
...
concatenation = (char*)malloc(len+len+len+1);
对于如此简单的任务,您的代码非常奇怪和复杂。你到底想达到什么目的 ?
您的问题在于您没有区分单个字符 (char
) 和一串字符 (char[]
)。
从上到下:
1) 您可以使用单引号分配一个 ASCII 值:
double character2 = '6';
double character1 = '.';
double character0 = '3';
2) 字符串以空字符结尾,这意味着容纳n个字符的字符串所需的字节数为n+1。因此,您至少需要两个字节才能将单个字符存储为字符串。
3) sprintf
存储一个字符串,这意味着它在最后一个字符之后存储一个终止空字符:
sprintf(buffer2,"%c",character2_int);
将单个字节从 character2_int
复制到 buffer2
,然后将终止空字符(十进制 0)写入 RAM 地址 &buffer2 + 1
.
4) strcpy()
和 strcat()
处理字符串,而不是单个 chars
。他们将继续 copy/concatenate chars
直到找到终止空字符。同样,不要忘记分配足够的 space 来包含终止空字符。