指针类型转换:对缓冲区长度的影响?
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;
【讨论】:
以上是关于指针类型转换:对缓冲区长度的影响?的主要内容,如果未能解决你的问题,请参考以下文章