2010-02-07 26 views
0

Char est 1 octet unsigned short est de 2 octetsConversion de type pointeur: effet sur la longueur du tampon?

Donc, si je jetai un char *-unsigned short *, va changer la longueur de la mémoire tampon?

Par exemple, je passe char * et la longueur à une fonction VUMeter. La fonction jette le char *-unsigned short *:

short* pln = (short*) buffer;` 

Maintenant, je boucle à travers le tampon, de sorte que je peux utiliser même longueur qui a été adoptée?

int peak=0; 
short* pln = (short*) buffer; 
for (int i=0; i<len; i++) 
{ 
    if(abs(pln[i]) > peak) 
    peak = abs(pln[i]); 
} 

Pour une raison quelconque, j'obtiens des erreurs d'application dans la boucle.

Répondre

1

Si la taille des éléments double, alors vous avez de la place pour la moitié des éléments. Lancer un pointeur ne le redimensionne pas, c'est supposer que vous savez ce que vous faites avec le pointeur. Donc non, vous ne pouvez pas vraiment lancer un char * sur un court * et attendre que les choses fonctionnent. Si vous avez besoin d'un short * avec les mêmes valeurs que dans le char *, vous devez allouer un tableau court et copier les éléments individuellement depuis le char *.

0

unsigned short peut ou non être de 2 octets. Regardons la mémoire pour votre exemple.

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

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

Si unsigned short est 2 octets, vous disposez d'un espace de valeur len/2unsigned short valeurs. Ou, plus généralement, vous avez un espace pour les valeurs len/nunsigned short, où n est égal à sizeof(unsigned short).

Vous ne pouvez pas diffuser un unsigned char * en unsigned char * et vous vous attendez à ce que les choses fonctionnent de manière portable. Maintenant, pour calculer peak, cela dépend de ce que vous essayez de faire. Si vous voulez trouver le maximum de lenunsigned char valeurs et enregistrer que dans peak, en boucle sur les valeurs fonctionnera:

size_t i; 
unsigned short peak = 0; 
for (i=0; i < len; ++i) { 
    if (buffer[i] > peak) { 
     peak = buffer[i]; 
    } 
} 

Toutefois, si vous voulez « combiner » sizeof(unsigned short) valeurs dans une valeur unsigned short, puis votre meilleur pari serait de calculer les nombres à la main.

En supposant que len est divisible par n, et le stockage big-endian, vous pouvez faire quelque chose comme ça (non testé):

#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

La mémoire qui est alloué ne changera pas jusqu'à ce que vous appelez * alloc(). Le fait que la taille du type de données soit de taille différente n'influencera que la "taille de pas" ("x + 1" indiquera x + 2 octets), mais vous disposerez de la moitié d'autant d'éléments. Personnellement, j'éviterais simplement de lancer un pointeur. Cela rendra probablement les données déjà présentes dans le bloc mémoire mal lues (deux octets séparés seront maintenant lus comme une seule valeur, complètement différente de ce que vous aviez en tête lors du remplissage du buffer avec des valeurs de 1 octet: deux valeurs suivantes 127, 127 deviendra une seule valeur: 65535, ce genre de chose). Et je pense que cela va aussi déclencher un avertissement dans le compilateur (au moins GCC se plaint d'une telle distribution).Je pense que ce que vous devez faire est la suivante:

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); 

À moins que mon code rapidement composé a un bug dans (je ne l'ai pas pris la peine de le vérifier), il faut faire ce que vous voulez atteindre: « cast » un pointeur de char * à uint16 *, mais aussi copier en toute sécurité les données sans modifier les valeurs (à moins qu'il y ait une valeur négative parmi les caractères, ofc).