串联在C字符数组:动态内存处理 [英] Concatenating a char array in C: dynamically handling memory
问题描述
我对我在做什么错在我的C程序困惑:我试图创建一个
开始,增加了6串'!值从传感器(用逗号隔开)读取,然后发送它的串行端口。示例输出将是:!5,5,5,5,5,5
或34,34,34,34,! 34,34
。
问题:由于传感器的值(在上面的例子中5或34)的范围从0到255,我也不在运行时知道我的字符数组需要有多大是。这意味着我要我要添加到我的字符串每次动态重新分配内存。下面是我尝试这样做,但我这样做是错误的,因为我什么也看不到在我的串行端口来(表示有一个运行时错误)。
我怎样才能正确地实现code为字符串动态分配内存?我试图使用的malloc
和的realloc
的行为不符合市场预期。
的char * convertIntToString(uint8_t有integerValue){
字符*海峡=的malloc(4); //最多3位数+ 1为空终止
utoa(integerValue,STR,10);
返回海峡;
}字符* CONCAT(字符* S1,字符* S2)
{
字符*结果=的malloc(strlen的(S1)+ strlen的(S2)+1); // + 1零终止
//在实际code,你会在malloc的检查错误在这里
的strcpy(结果是,S1);
的strcat(结果,S2);
返回结果;
}INT主要(无效)
{
uint8_t有analogValue;
字符* outputStr =的malloc(1); //字符数组= 1元initalize大小 而(1){
outputStr = realloc的(outputStr,1);
outputStr = CONCAT(outputStr,!);
analogValue = ReadADC(0);
outputStr = CONCAT(outputStr,convertIntToString(analogValue));
的for(int i = 0;我小于5;我++){
outputStr =的concat(outputStr,,);
outputStr = CONCAT(outputStr,convertIntToString(analogValue));
}
CDC_Device_SendString(安培; VirtualSerial_CDC_Interface,outputStr); //通过USB发送字符串
免费(outputStr);
}
}
您正在运行到不确定的行为,因为 outputStr
的内容不会在第一次声明中正确初始化内在,而
循环。
outputStr = realloc的(outputStr,1); // outputStr未初始化。
他们更改为:
outputStr = realloc的(outputStr,2);
的strcpy(outputStr,!);
您也渗出了一大堆的内存。从 convertToString
返回的值是永远免费
D。
您可以通过改变策略,一点点避免这样的问题。
改变功能到期望的字符串并使用它。
的char * convertIntToString(uint8_t有integerValue,
字符*海峡)
{
utoa(integerValue,STR,10);
返回海峡;
}
然后,更改其用法为:
outputStr = CONCAT(outputStr,convertIntToString(analogValue,STR));
您也泄漏内存,由于使用的是 CONCAT
。
outputStr = CONCAT(outputStr,);
这泄漏 outputStr
的旧值。你需要保持 outputStr
的旧价值的时间长一点,所以你可以免费
了。
下面是我为,而
环路建议:
而(1){ outputStr = realloc的(outputStr,2);
的strcpy(outputStr,!); analogValue = ReadADC(0); 炭海峡[4]; //这是你所需要的最大。
//没有必要malloc和自由。 outputStr = CONCAT(outputStr,convertIntToString(analogValue,STR)); 的for(int i = 0;我小于5;我++){ 字符* =中newstr CONCAT(outputStr,); //使用新的内存之前释放旧内存
免费(outputStr);
outputStr =中newstr; =中newstr CONCAT(outputStr,convertIntToString(analogValue,STR)); //使用新的内存之前释放旧内存
免费(outputStr);
outputStr =中newstr;
}
CDC_Device_SendString(安培; VirtualSerial_CDC_Interface,outputStr); //通过USB发送字符串
免费(outputStr);
}
I'm confused on what I'm doing wrong in my C program: I'm trying to create a string that begins with a '!'
and adds 6 values read from a sensor (separated by commas) and then sends it over a serial port. A sample output would be: "!5,5,5,5,5,5"
or "!34,34,34,34,34,34"
.
The problem: Because the sensor values (5 or 34 in the example above) can range from 0 to 255, I don't know at runtime how big my char array needs to be. This means I have to dynamically reallocate memory every time I want to add to my string. Below is my attempt to do so, but I'm doing this wrong because I see nothing coming across my serial port (indicating that there's a runtime error).
How can I properly implement code to allocate memory dynamically for a string? My attempts to use malloc
and realloc
aren't behaving as expected.
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);
}
}
You are running into undefined behavior since the contents of outputStr
are not initialized properly in the first statement inside the while
loop.
outputStr = realloc(outputStr, 1); // outputStr is not initialized.
Change them to:
outputStr = realloc(outputStr, 2);
strcpy(outputStr, "!");
You are also leaking a whole bunch of memory. The value returned from convertToString
is never free
d.
You can avoid that problem by changing the strategy a little bit.
Change the function to expect a string and use it.
char* convertIntToString(uint8_t integerValue,
char* str)
{
utoa(integerValue, str, 10);
return str;
}
Then, change its usage as:
outputStr = concat(outputStr, convertIntToString(analogValue, str));
You are also leaking memory due to the way you are using concat
.
outputStr = concat(outputStr, ",");
That leaks the old value of outputStr
. You need to keep the old value of outputStr
for a bit longer so you can free
it.
Here's my suggestion for the while
loop:
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);
}
这篇关于串联在C字符数组:动态内存处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!