串联在C字符数组:动态内存处理 [英] Concatenating a char array in C: dynamically handling memory

查看:134
本文介绍了串联在C字符数组:动态内存处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对我在做什么错在我的C程序困惑:我试图创建一个 开始,增加了6串'!值从传感器(用逗号隔开)读取,然后发送它的串行端口。示例输出将是:!5,5,5,5,5,534,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 freed.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆