2010-02-07 71 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)。