【问题标题】: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]);
}  

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

【问题讨论】:

    标签: c short unsigned-char


    【解决方案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;
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2015-01-31
          • 2019-02-08
          • 2013-04-25
          • 2021-03-13
          • 2018-04-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多