2010-02-07 5 views
0

Char 1 байт unsigned short составляет 2 байтаПреобразование типа указателя: влияние на длину буфера?

Так что, если я бросил char * к unsigned short *, будет ли он изменить длину буфера?

Например, я прохожу char * и длину до функции VUMTER. Функция отбрасывает 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 *.

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

объем памяти, выделяется не изменится, пока вы не вызовете * 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).