在c中分配空间并连接到无符号字符数组

Posted

技术标签:

【中文标题】在c中分配空间并连接到无符号字符数组【英文标题】:Allocating space and concatenating to a unsigned char array in c 【发布时间】:2011-10-24 21:43:34 【问题描述】:

我正在为一个项目创建一个图像压缩器。我为图像中的值生成代码的方式是,对于每个灰度值(从 0 到 254),在一个名为 codeArray(Huffman 编码)的数组中都有一个 char* 代码。

要求有一个返回 unsigned char* 的函数。我遍历每个像素并使用 codeArray 将该像素的灰度值转换为代码。

我需要使 unsigned char 数组随着更多灰度值被转换并连接到数组末尾而动态增长。

    unsigned char* encodedString = malloc(sizeof(char));    

    int width = image->width; //width and height of image structure
    int height = image->height;
    int row, col;
    for(row = 0; row<height; row++)
        for(col = 0; col<width; col++)
        
            int value = image->pixel[row][col]; //gets the grey value

            encodedString = realloc(encodedString, (strlen(encodedString)+strlen(codeArray[value])));

            strcat(encodedString, codeArray[value]);

        

我尝试在 strcat 之后使用 print 语句运行它,发现它一直打印到有 24 个字符,然后开始打印垃圾,然后 Seg 出现故障。

帮助表示赞赏!

【问题讨论】:

【参考方案1】:

您在未初始化的缓冲区上调用 strlen(encodedString)。这是未定义的行为。您需要将encodedString 的初始内容归零。

unsigned char* encodedString = malloc(1);
//check for malloc errors 
encodedString[0] = '\0';

看起来你侥幸逃脱了那个错误,但马上又犯了另一个错误。您的reallocstrlen(encodedString)+strlen(codeArray[value]) 腾出空间,但您忘记为零终结符分配空间。大概这就是导致strcat 爆炸的原因。通过将大小参数添加到 realloc 来解决该问题。

正如@Lou 指出的那样,您的 realloc 策略的性能可能很差。在函数开始时分配一次缓冲区可能会更好,因为大概可以对其大小设置一个相对严格的上限。

而且你也不应该写ptr = realloc(ptr, ...),因为你将无法从realloc 的失败中恢复并且总是会泄漏。但与其他故障相比,这确实是一个细微差别。

【讨论】:

+1。或多或少是我的观察,除了我喜欢在每一个机会宣扬realloc危险;) @David - 更不用说为您添加到编码字符串的每个值调用 realloc() 一次的效率。要么计算你需要多少空间并提前分配,要么至少使用编码字符串的一些二进制增长(即每次需要增加大小时,将编码字符串数组的大小加倍)。 @larsmans re。 realloc,我知道你的意思,但我觉得主要的重点应该是更明显的错误。这种性质的每一个问题都让我更加欣赏具有真正字符串数据类型的语言的乐趣。 谢谢!我在分配内存方面从来没有很强的能力,也从来没有真正确定我是否做得对。另外,我知道我想分配给一个单独的指针并进行错误检查——只是想让它保持干净和简单。

以上是关于在c中分配空间并连接到无符号字符数组的主要内容,如果未能解决你的问题,请参考以下文章

动态数组C风格字符串字符串字面值

在 Fortran 中分配字符数组

在 Fortran 中分配字符数组

C程序:用函数更新无符号字符指针数组

为啥在 c++ 中分配 char 数组元素时,分配的字符被破坏?

数组,数字包装类,字符串的处理