我对我在C程序中出错的原因感到困惑:我试图创建一个以'!'
开头的字符串,并添加从传感器读取的6个值(用逗号分隔)然后通过串口发送。示例输出为:"!5,5,5,5,5,5"
或"!34,34,34,34,34,34"
。
问题:因为传感器值(上例中的5或34)的范围可以从0到255,所以我在运行时不知道我的char数组需要多大。这意味着我每次要添加到字符串时都必须动态重新分配内存。下面是我尝试这样做的,但我做错了,因为我看到没有任何东西进入我的串口(表明存在运行时错误)。
如何正确实现代码以动态为字符串分配内存?我尝试使用malloc
和realloc
的行为不符合预期。
char* convertIntToString(uint8_t integerValue){
char *str = malloc(4); //up to 3 digits + 1 for null termination
utoa(integerValue, str, 10);
return str;
}
char* concat(char *s1, char *s2)
{
char *result = malloc(strlen(s1)+strlen(s2)+1);//+1 for the zero-terminator
//in real code you would check for errors in malloc here
strcpy(result, s1);
strcat(result, s2);
return result;
}
int main(void)
{
uint8_t analogValue;
char *outputStr = malloc(1); //initalize size of char array = 1 element
while (1) {
outputStr = realloc(outputStr, 1);
outputStr = concat(outputStr, "!");
analogValue = ReadADC(0);
outputStr = concat(outputStr, convertIntToString(analogValue));
for(int i = 0; i < 5; i++){
outputStr = concat(outputStr, ",");
outputStr = concat(outputStr, convertIntToString(analogValue));
}
CDC_Device_SendString(&VirtualSerial_CDC_Interface, outputStr); //send string via USB
free(outputStr);
}
}
答案 0 :(得分:2)
由于在outputStr
循环内的第一个语句中未正确初始化while
的内容,因此您遇到了未定义的行为。
outputStr = realloc(outputStr, 1); // outputStr is not initialized.
将它们更改为:
outputStr = realloc(outputStr, 2);
strcpy(outputStr, "!");
你也在泄漏一大堆内存。从convertToString
返回的值绝不是free
d。
您可以通过稍微改变策略来避免这个问题。
将函数更改为需要字符串并使用它。
char* convertIntToString(uint8_t integerValue,
char* str)
{
utoa(integerValue, str, 10);
return str;
}
然后,将其用法更改为:
outputStr = concat(outputStr, convertIntToString(analogValue, str));
由于您使用concat
的方式,您也在泄漏内存。
outputStr = concat(outputStr, ",");
泄漏outputStr
的旧值。您需要将outputStr
的旧值保留更长时间才能free
。
以下是我对while
循环的建议:
while (1) {
outputStr = realloc(outputStr, 2);
strcpy(outputStr, "!");
analogValue = ReadADC(0);
char str[4]; // This is the max you need.
// There is no need to malloc and free.
outputStr = concat(outputStr, convertIntToString(analogValue, str));
for(int i = 0; i < 5; i++){
char* newStr = concat(outputStr, ",");
// free the old memory before using the new memory
free(outputStr);
outputStr = newStr;
newStr = concat(outputStr, convertIntToString(analogValue, str));
// free the old memory before using the new memory
free(outputStr);
outputStr = newStr;
}
CDC_Device_SendString(&VirtualSerial_CDC_Interface, outputStr); //send string via USB
free(outputStr);
}
答案 1 :(得分:0)
以下代码:
现在是代码:
#include <string.h>
int main(void)
{
uint8_t analogValue;
char outputStr[20];
char temp[4];
while (1)
{
memset( outputStr, 0, sizeof(outputStr) );
outputStr = strcat(outputStr, "!");
for(int i = 0; i < 5; i++)
{
analogValue = ReadADC(0);
if( i < 4 )
sprintf( temp, "%u,", analogValue );
else
sprintf( temp, "%u", analogValue );
strcat( outputStr, temp );
}
CDC_Device_SendString(&VirtualSerial_CDC_Interface, outputStr); //send string via USB
}
}