在 C 中连接 char 数组:动态处理内存

2023-12-26

我对我在 C 程序中做错了什么感到困惑:我正在尝试创建一个以 a 开头的字符串'!'并添加从传感器读取的 6 个值(用逗号分隔),然后通过串行端口发送。示例输出如下:"!5,5,5,5,5,5" or "!34,34,34,34,34,34".

问题:因为传感器值(上例中的 5 或 34)范围可以从 0 到 255,所以我在运行时不知道我的 char 数组需要有多大。这意味着每次我想添加到字符串时都必须动态地重新分配内存。下面是我这样做的尝试,但我做错了,因为我没有看到串行端口上有任何内容(表明存在运行时错误)。

如何正确实现为字符串动态分配内存的代码?我尝试使用malloc and 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);
    }  
}

由于内容的内容,您遇到了未定义的行为outputStr在第一个语句中没有正确初始化while loop.

   outputStr = realloc(outputStr, 1); // outputStr is not initialized.

将它们更改为:

    outputStr = realloc(outputStr, 2);
    strcpy(outputStr, "!");

您还泄漏了一大堆内存。返回值来自convertToString从来没有freed.

您可以通过稍微改变策略来避免这个问题。

更改函数以期望字符串并使用它。

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 it.

这是我的建议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);
}  
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 C 中连接 char 数组:动态处理内存 的相关文章

随机推荐