2010-02-07 50 views
0

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 *中的值相同的short *,你需要分配一个简短的数组并且单独从char *中拷贝元素。

0

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

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

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

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

你不能投unsigned char *unsigned char *,并期望事情可移植工作。现在,要计算peak,这取决于你正在尝试做什么。如果你想找到的最大的lenunsigned 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; 
    } 
} 
0

是已分配将不会改变,直到你调用*页头的存储器()。数据类型大小不同的事实只会影响“步长”(“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); 

除非我迅速作出了代码中有一些bug(我没有刻意去检查它),它应该做你想要达到的目标:“中投”一个从char *到uint16 *的指针,但也可以在不改变值的情况下安全地复制数据(除非字符之间有一个负值,ofc)。