Puntatori e array unsigned char

di il
15 risposte

Puntatori e array unsigned char

Ho un array bidimensionale inizializzato int A[280][272] con tutti i suoi valori. Da questo array tramite un puntatore devo estrarne il contenuto. Per fare ciò ho semplicemente ricostruito l'array tramite un puntatore che punta al primo elemento con il seguente codice:

    int *a=NULL;
    int m=(sizeof(*A)/4);
    int n=(sizeof(A)/4)/m;
    int i,j;

    a=&(A[0][0]);


    for(i=0;i<n;i++)

    {

        for(j=0;j<m;j++)

        {

            A[i][j]=*(a+i*m+j);

        }


    }
Il codice funziona e ottengo esattamente l'array di partenza. Il problema è che il tipo int occupa 4 byte e ho bisogno di ridurre la dimensione dell'array, quindi ho dichiarato quest'ultimo come
unsigned char A[280][272], in modo che ogni elemento dell'array occupi 1 byte, ma a questo punto non posso modificare il codice come segue:

    unsigned char *a=NULL;
    int m=(sizeof(*A));
    int n=(sizeof(A))/m;
    int i,j;

    a=&(A[0][0]);


    for(i=0;i<n;i++)

    {

        for(j=0;j<m;j++)

        {

            A[i][j]=*(a+i*m+j);

        }


    }
In uscita ho dei caratteri strani perchè suppongo che non posso usare un puntatore unsigned char, ma usando un puntatore a int comunque il compilatore mi dà errore, pertanto come posso risolvere il problema? Ho bisogno di ricostruire l'array come fatto nel primo codice ma dichiarando quest'ultimo come unsigned char..

L'array è composto solamente da 1 e 0 quindi in realtà quello che conta è solamente il bit meno significativo, per questo voglio ridurre la dimensione a unsigned char.

15 Risposte

  • Re: Puntatori e array unsigned char

    Non si è capito un gran che.
    Tu hai A che è una matrice (non array) contenente un valore 1 o 0 di tipo int.
    Ora la vuoi copiare su un'altra matrice di dimensioni minori
    potresti fare semplicemente:
    
    ...
    unsigned char nuovo[MAXY][MAXX];
    
    for ( y = 0; y < MAXY; y++)
        for ( x = 0; x < MAXX; x++)
            nuovo[y][x] = A[y][x];
    ...
    
    oppure spiega meglio cosa devi fare,ovvero cosa hai(e come l'hai ottenuto) e cosa vuoi fare.
  • Re: Puntatori e array unsigned char

    Vb ... con array si intendono sia i vettori che le matrici ...
  • Re: Puntatori e array unsigned char

    Si ok, ho un array bidimensionale, quindi una matrice. Mi spiego meglio, allora la matrice che sto considerando rappresenta un'immagine binaria, devo elaborare questa immagine attraverso un algoritmo, per poi andare a programmare un processore. Visto che il processore ha poca memoria definendo la matrice con int, il programma non entra all'interno della memoria locale del processore, mentre entrerebbe se dichiaro la matrice come unsigned char. Il problema è appunto che dichiarando la matrice come unsigned char, poi si pone il problema di come utilizzare il puntatore, il codice completo del programma è il seguente:
    
    #include <stdio.h>
    #include <stdlib.h>
    #include "matrix.h"
    #include "imelaborate.h"
    
    int main(int argc, char *argv[])
    {
    
    int *a=NULL;
    int *v=NULL;
    int i,j,s;
    
    //Ricezione immagine in ingresso
    
    int m=(sizeof(*A)/4);
    int n=(sizeof(A)/4)/m;
    
    
    a=&(A[0][0]);
    
    //Elaborazione dell'immagine
    
    v=imelaborate(a,n,m,s);
    
    //Ricostruzione immagine dal puntatore
    
        for(i=0;i<n;i++)
    
        {
    
            for(j=0;j<m;j++)
    
            {
    
                A[i][j]=*(v+i*m+j);
    
            }
    
    
        }
    
    
    
    Praticamente la funzione imelaborate effettua un'elaborazione sulla matrice, restituendo il puntatore al primo elemento A[0][0].
    Quindi ricapitolando ho una matrice A di 1 e 0 (rappresenta la mia immagine binaria), ho un puntatore a al primo elemento della matrice A[0][0], utilizzo la funzione imelaborate che prende come argomento il puntatore a, le dimensioni di A, più un altro elemento s che mi serve per effettuare l'elaborazione, a questo punto imelaborate mi restituisce il puntatore v che punta a A[0][0], primo elemento della matrice elaborata e infine attraverso l'ultimo ciclo for dal puntatore v mi ricostruisco tutta la matrice dopo l'elaborazione. Quindi alla fine ottengo la mia matrice A elaborata. A questo punto io vorrei fare la stessa elaborazione, ma utilizzando come dimensione della matrice unsigned char così che da poter programmare il processore con il codice. Quindi a tal fine come posso cambiare il codice?
  • Re: Puntatori e array unsigned char

    Ma il prototipo della funzione imelaborate qual è? Cosa si aspetta e cosa restituisce questa funzione? E' una tua funzione?
  • Re: Puntatori e array unsigned char

    La funzione si aspetta un puntatore che punta al primo elemento dell'array A[0][0] e restituisce un puntatore che punta sempre al primo elemento dell'array A[0][0] elaborato. Il prototipo della funzione è il seguente:
    int *imelaborate(int *p,int n, int m, int s);
    La funzione l'ho creata io
  • Re: Puntatori e array unsigned char

    Quindi la funzione lavora con array di interi. Devi modificarla per lavorare con array di unsigned char (e con puntatori a unsigned char) !
  • Re: Puntatori e array unsigned char

    Si ma sostituendo il codice nel seguente modo:
    
    #include <stdio.h>
    #include <stdlib.h>
    #include "matrix.h"
    #include "imelaborate.h"
    
    int main(int argc, char *argv[])
    {
    
    unsigned char *a=NULL;
    unsigned char *v=NULL;
    int i,j,s;
    
    //Ricezione immagine in ingresso
    
    int m=(sizeof(*A));
    int n=(sizeof(A))/m;
    
    
    a=&(A[0][0]);
    
    //Elaborazione dell'immagine
    
    v=imelaborate(a,n,m,s);
    
    //Ricostruzione immagine dal puntatore
    
        for(i=0;i<n;i++)
    
        {
    
            for(j=0;j<m;j++)
    
            {
    
                A[i][j]=*(v+i*m+j);
    
            }
    
    
        }
    
    
    
    Modificando anche la funzione e il prototipo:
    
    unsigned char *imelaborate(unsigned char *p,int n, int m, int s);
    
    In uscita non ottengo niente se non dei caratteri strani, quando dovrei ottenere degli 0 e 1 e non capisco perchè
  • Re: Puntatori e array unsigned char

    Non basta, ovviamente, modificare il prototipo. Bisogna modificare il codice della funzione.

    E' possibile vedere il codice della funzione? E come è dichiarato l'array A?
  • Re: Puntatori e array unsigned char

    Si ok questo è il codice della funzione:
    unsigned char *imelaborate(unsigned char *p,int n, int m, int s)
    
    {
        int i,j,k,h;
        int inc=0;
        unsigned char A[n][m];
        unsigned char C[n+(s-1)][m+(s-1)];
    
    
       //Ricostruzione immagine dal puntatore
        for(i=0;i<n;i++)
    
        {
    
            for(j=0;j<m;j++)
    
            {
    
                A[i][j]=*(p+i*m+j);
    
            }
    
    
        }
    
    
          //Creazione della matrice C per tener conto dei bordi
           for (i=0; i<n+(s-1); i++)
             {
               for (j=0; j<m+(s-1); j++)
                 {
                    C[i][j]=1;
                 }
             }
    
    
         //Riempimento della matrice C con la matrice A
            for (i=(s-1)/2; i<n+(s-1)/2; i++)
            {
              for (j=(s-1)/2; j<m+(s-1)/2; j++)
                {
                  C[i][j]=A[i-(s-1)/2][j-(s-1)/2];
                }
            }
    
         //Elaborazione dell'immagine
           for (i=(s-1)/2; i<n+(s-1)/2; i++)
            {
              for(j=(s-1)/2; j<m+(s-1)/2; j++)
                {
                  for (k=-(s-1)/2; k<(s+1)/2; k++)
                   {
                      for (h=-(s-1)/2; h<(s+1)/2; h++)
                       {
                          if(C[i+k][j+h]==1)
                           {
                             inc=inc+1;
                           }
    
                          if (k==(s-1)/2 && h==(s-1)/2)
                           {
                              if(inc==s*s)
                               {
                                A[i-(s-1)/2][j-(s-1)/2]=1;
                               }
    
                               else
                               {
                                A[i-(s-1)/2][j-(s-1)/2]=0;
    
                               }
    
                              inc=0;
                           }
                       }
                   }
                }
             }
    
    unsigned char *v1=&(A[0][0]);
    
    return v1;
    
    }
    
    
    Mentre questa è la matrice:
    
    
    unsigned char A[280][272]={...};
    
    
    Il contenuto della matrice A sono tutti 0 e 1, non l'ho scritto tutto perchè è troppo grande.
  • Re: Puntatori e array unsigned char

    Questa cosa
    
    unsigned char *v1=&(A[0][0]);
    
    return v1;
    
    non la puoi fare perché così restituisci il puntatore ad un array che all'uscita della funzione non esiste più dato che è allocato nello stack.

    Puoi avere dei crash o leggere sporcizia.

    La cosa migliore è usare la malloc per allocare l'array di cui vuoi restituire il puntatore.
  • Re: Puntatori e array unsigned char

    Ok comunque riscrivendo tutto in un nuovo file il codice funziona correttamente (evidentemente il compilatore si era impallato), però come dici sarebbe meglio utilizzare la funzione malloc e liberare la memoria dopo la chiamata della funzione, quindi all'interno della funzione, dopo l'elaborazione dell'immagine, dovrei scrivere qualcosa del tipo:
    
    
    matrix=(unsigned char*)malloc(n*m,sizeof(unsigned char));
    
    for(i=0;i<n;i++)
    
        {
    
            for(j=0;j<m;j++)
    
            {
    
                *(matrix+i*m+j)=A[i][j];
    
            }
    
        }
    
    return matrix;
    
    free(matrix);
    
    matrix=NULL;
    
    
    È corretto?
  • Re: Puntatori e array unsigned char

    return matrix;
    
    free(matrix);
    
    matrix=NULL;
    Codice dopo return significa "unreachable code" ovvero codice non raggiungibile.
    Devi liberare la memoria fuori dalla funzione
  • Re: Puntatori e array unsigned char

    Ok però come faccio a liberare la memoria fuori dalla funzione, se il puntatore matrix lo definisco all'interno della matrice?
  • Re: Puntatori e array unsigned char

    Ma il puntatore lo restituisci, no?
Devi accedere o registrarti per scrivere nel forum
15 risposte