Przekazywanie tablicy dynamicznej pomiędzy funkcjami

0

Siemka,
mam do napisania program, który będzie sobie radził z obrazami PGM/PPM.
Funkcja "czytaj" wczytuje sobie informacje o pliku(P2/P3, szerokosc, wysokosc max kolor) a następnie wczytuje wartosci pikseli obrazu do tablicy dynamicznej.
Kiedy operacja się powiedzie, przekazuje wszytskie wartosci do funkcji main.
Problem pojawia się przy próbie zapisania wartości z tablicy "obraz" do pliku.
Przypuszczam, że źle przekazuje tablice z czytaj do main, ale nie znam innego sposobu.
Proszę o pomioc, jak to zrobic poprawnie, zeby działało.

czytaj.c

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include"czytaj.h"

#define DL_LINII 1024      /* Dlugosc buforow pomocniczych */


int czytaj(FILE *plik_we,int **tablica,int *wymx,int *wymy, int *szarosci,char numerMagiczny[2]) {
    char buf[DL_LINII];      /* bufor pomocniczy do czytania naglowka i komentarzy */
    int znak;                /* zmienna pomocnicza do czytania komentarzy */
    int koniec=0;            /* czy napotkano koniec danych w pliku */
    int i,j;
    
    
    
    /*Sprawdzenie czy podano prawid≥owy uchwyt pliku */
    if (plik_we==NULL) {
        fprintf(stderr,"Blad: Nie podano uchwytu do pliku\n");
        return(0);
    }
    
    /* Sprawdzenie "numeru magicznego" - powinien byÊ P2 */
    if (fgets(buf,DL_LINII,plik_we)==NULL)   /* Wczytanie pierwszej linii pliku do bufora */
        koniec=1;                              /* Nie udalo sie? Koniec danych! */
    
    if ( (buf[0]='P') && ((buf[1]='2') | (buf[1]='3')) ) { /* Czy jest magiczne "P2/P3"? */
        numerMagiczny[0]=buf[0];
        numerMagiczny[1]=buf[1];}
        else{
        fprintf(stderr,"Blad: To nie jest plik PGM/PPM\n");
        return(0);
        }
    
    /* Pominiecie komentarzy */
    do {
        if ((znak=fgetc(plik_we))=='#') {         /* Czy linia rozpoczyna sie od znaku '#'? */
            if (fgets(buf,DL_LINII,plik_we)==NULL)  /* Przeczytaj ja do bufora                */
                koniec=1;                   /* Zapamietaj ewentualny koniec danych */
        }  else {
            ungetc(znak,plik_we);                   /* Gdy przeczytany znak z poczatku linii */
        }                                         /* nie jest '#' zwroc go                 */
    } while (znak=='#' && !koniec);   /* Powtarzaj dopoki sa linie komentarza */
    /* i nie nastapil koniec danych         */
    
    /* Pobranie wymiarow obrazu i liczby odcieni szarosci */
    if (fscanf(plik_we,"%d %d %d",wymx,wymy,szarosci)!=3) {
        fprintf(stderr,"Blad: Brak wymiarow obrazu lub liczby stopni szarosci\n");
        return(0);
    }
    
    
    tablica = (int **)malloc(*wymx * sizeof(int *)); //Zdefiniowanie tablicy dynamicznej
                                                    //Przystosowanej dla rozmiarow obrazu
    for (i = 0; i < *wymy; ++i)
        tablica[i] = (int *)malloc(*wymy * sizeof(int));
    
    
    /* Pobranie obrazu i zapisanie w tablicy obraz_pgm*/
    for (i=0;i<*wymx;i++) {
        for (j=0;j<*wymy;j++) {
            if (fscanf(plik_we,"%d", &tablica[i][j])!=1) {
                fprintf(stderr,"Blad: Niewlasciwe wymiary obrazu\n");
                return(0);
            }
        }
    }
    return *wymx**wymy;   /* Czytanie zakonczone sukcesem    */
}                       /* Zwroc liczbe wczytanych pikseli */

main.c

#include"display.h"
#include"czytaj.h"

int main() {
    FILE *plik;
    int *obraz ; //tablica z obrazem
    int wymx,wymy,odcieni; //dane obrazu
    char nazwa[100];
    char numerMagiczny[2];
    int i, j;
    int odczytano = 0;

    int menu; //menu
    
    do { //Menu uzytkownika
        
        printf("Menu: \n");
        printf("\t1 - Wczytanie obrazu \n");
        printf("\t2 - Wyświetlenie obrazu \n");
        printf("\t3 - Zapis obrazu \n");
        printf("\t4 - Zakończenie \n\n");
        printf("Twoj wybor: ");
        scanf("%d", &menu); //Dokonanie wyboru
        
        switch(menu){
            case 1: printf("Wybrano wczytanie obrazu \n");
                
                printf("Podaj nazwe pliku:\n"); /* Wczytanie zawartosci wskazanego pliku do pamieci */
                scanf("%s",nazwa);
                plik=fopen(nazwa,"r");
                
                if (plik != NULL) {       /* co spowoduje zakomentowanie tego warunku */
                    odczytano = czytaj(plik,&obraz,&wymx,&wymy,&odcieni,numerMagiczny);
                    fclose(plik);
                    printf("Pomyślnie wczytano obraz\n");
                }
                break;
                
            case 2: printf("Wybrano wyswietlenie obrazu \n");
                if (plik != NULL) {       /* co spowoduje zakomentowanie tego warunku */
                    odczytano = czytaj(plik,&obraz,&wymx,&wymy,&odcieni,numerMagiczny);
                    fclose(plik);
                }
                /* Wyswietlenie poprawnie wczytanego obraza zewnetrznym programem */
                if (odczytano != 0)
                    wyswietl(nazwa);
                break;
                
            case 3: printf("Wybrano zapis obrazu \n"); //Sprawdzenie czy wczytano plik
                plik=fopen(nazwa, "w");
                
                if ((plik=fopen(nazwa, "w")) == NULL){
                    fprintf(stderr,"Blad: Nie wczytano pliku\n");
                    break;
                }
                else{
                    fprintf(plik, "%c%c\n", numerMagiczny[0], numerMagiczny[1]); /*Zapisanie magicznego numeru*/
                    fprintf(plik, "# Plik edytowany \n");
                    fprintf(plik, "%d %d\n%d\n", wymx, wymy, odcieni); /*Zapisanie szerokosci, wysykosci i max wartosci szarosci*/
                    for (i = 0; i < wymy; i++) {
                        for (j = 0; j < wymx; j++)
                            fprintf(plik, "%d ", obraz[i][j]);
                        fprintf(plik, "\n");}
                    fclose(plik);
                    printf("Obraz zapisano pomyślnie \n");
                }
                break;
                
        }
    }while(menu!=4);
    
    printf("Program zakończył działanie. \n"); //Koniec programu
    
    return odczytano;
}
0
if ( (buf[0]='P') && ((buf[1]='2') | (buf[1]='3')) )  ...

Nie powinny być dwa znaki || ?

Masz tablice dynamiczną , a nigdzie jej na zwalniasz "free()"

Edit.
Według mnie taka danymaczna tablica nie jest potrzebna, bo ogólnie wymiary zczytujesz i wychodzi X na Y, i zawsze wymiar bedzie X na Y , nigdy nie bedzie w obrazie tak, żeby np. nie było potrzeba ostatniej wartości z kolumny, więc jej nie będzie.

Ogólnie to co tutaj stworzyłeś to nie jest do końca tablica dynamiczna dwuwymiarowa, jest "jednowymiarowa tablica zawierająca wskaźniki do tablic jednowymiarowych". Znalazłem na internecie coś takiego:

int main()
{
  int m=4,n=3;
  int** arr;
  allocate_mem(&arr,n,m);
}

int* allocate_mem(int*** arr, int n, int m)
{
  *arr = (int**)malloc(n * sizeof(int*));
  int *arr_data = malloc( n * m * sizeof(int));
  for(int i=0; i<n; i++)
     (*arr)[i] = arr_data + i * m ;
  return arr_data; //free point
} 

do delokowanie tablicy:

void deallocate_mem(int*** arr, int* arr_data){
    free(arr_data);
    free(*arr);
}

Takie rozwiązanie wydaje mi się troszeczkę sensowniejsze.

1 użytkowników online, w tym zalogowanych: 0, gości: 1