指针类型转换:对缓冲区长度的影响?

Posted

技术标签:

【中文标题】指针类型转换:对缓冲区长度的影响?【英文标题】:Pointer type conversion: effect on buffer length? 【发布时间】:2010-02-07 18:49:13 【问题描述】:

Char 是 1 个字节 unsigned short 是 2 个字节

那么如果我将char * 转换为unsigned short *,它会改变缓冲区的长度吗?

例如,我将 char * 和长度传递给 VUMeter 函数。该函数将char * 转换为unsigned short *

short* pln = (short*) buffer;`

现在我循环遍历缓冲区,那么我可以使用传递的相同长度吗?

int peak=0;
short* pln = (short*) buffer;
for (int i=0; i<len; i++)

  if(abs(pln[i]) > peak)
     peak = abs(pln[i]);
  

由于某种原因,我在循环中遇到了应用程序错误。

【问题讨论】:

【参考方案1】:

如果元素的大小加倍,那么你有空间容纳一半的元素。投射指针不会调整它的大小,基本上是假设你知道你在用指针做什么。

所以不,您不能真正将 char * 转换为短 * 并期望一切正常。如果您需要一个短 * 与 char * 中的值相同,则需要分配一个短数组并从 char * 中单独复制元素。

【讨论】:

【参考方案2】:

在调用 *alloc() 之前,分配的内存不会改变。数据类型大小不同的事实只会影响“步长”(“x+1”将指向 x + 2 个字节),但您将有一半的元素空间。

就个人而言,我会避免简单地投射指针。它可能会使内存块中已经存在的数据被误读(两个单独的字节现在将作为单个值读取,这与您在用 1 字节值填充缓冲区时的想法完全不同:两个后续值 127, 127 将成为单个值:65535,诸如此类)。而且我认为它也会在编译器中引发警告(至少 GCC 抱怨这样的演员表)。我认为你应该做的是:

int x = SOMEVAL;
char * cptr = malloc(x*sizeof(char));
/* some code here - fill cptr with data */
uint16 * sptr = malloc(x*sizeof(uint16));
int i;
for (i = 0; i < x; i++) 
    *(sptr+i) = (uint16)(*(cptr+i));

free(cptr);

除非我快速编写的代码中有一些错误(我没有费心检查它),它应该做你想要实现的:将指针从 char*“转换”到 uint16*,但也可以安全地复制不改变值的数据(除非字符之间存在负值,ofc)。

【讨论】:

【参考方案3】:

unsigned short 可能是也可能不是 2 个字节。让我们看看你的例子的内存。

+---+---+---+     +---+---+---+
|   |   |   | ... |   |   |   |
+---+---+---+     +---+---+---+

|<-------- len bytes -------->|

如果 unsigned short 的长度为 2 个字节,则您的空间价值为 len/2 unsigned short 值。或者,更一般地说,您有空间存放 len/n unsigned short 值,其中 n 等于 sizeof(unsigned short)

您不能将 unsigned char * 转换为 unsigned char * 并期望事情可以移植。现在,要计算peak,这取决于您要做什么。如果您想找到 len unsigned char 值的最大值,并将其保存到 peak,则循环这些值将起作用:

size_t i;
unsigned short peak = 0;
for (i=0; i < len; ++i) 
    if (buffer[i] > peak) 
        peak = buffer[i];
    

但是,如果您想将 sizeof(unsigned short) 值“组合”成一个 unsigned short 值,那么最好的办法是手动计算这些数字。

假设len 可以被n 整除,并且大端存储,您可以这样做(未经测试):

#include <stdio.h>
#include <limits.h> 

size_t factor = sizeof(unsigned short);
size_t n = len / factor;
size_t i;
unsigned short peak = 0;
if (len % factor != 0) 
    fprintf(stderr, "Extra data at the end\n");
   
for (i=0; i < n; ++i) 
    size_t j;
    unsigned short test = 0;
    for (j=0; j < factor; ++j) 
        test = (test << CHAR_BIT)  + buffer[i*factor+j];
    
    if (test > peak) 
        peak = test;
    

【讨论】:

以上是关于指针类型转换:对缓冲区长度的影响?的主要内容,如果未能解决你的问题,请参考以下文章

请问知道一个jpg的二进制数据指针和数据长度,怎么转换成Mat数据类型?

为啥在使用单指针传递给函数时必须对二维数组进行类型转换?

数据存储及类型转换

为啥对非指针结构进行类型转换会给出语法错误

常见异常与引用数据类型转换

易语言指针转换及调用方法