Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

θελω να δημιουργησω 2διαστατο πινακα και ενω εχω διαβασει καπου κανει conflict ...

Ο κωδικας ειναι 

 

 
  
int m,n,i,j;
int data[][];

 

 ** data=(int **)malloc(m*sizeof(int *));
    for(i=0;i<m;i++)
        data=(int *)malloc(n*sizeof(int));  
 
Τι λαθος κανω ?
Δημοσ.

 

θελω να δημιουργησω 2διαστατο πινακα και ενω εχω διαβασει καπου κανει conflict ...

Ο κωδικας ειναι 

 

 
  

int m,n,i,j;
int data[][];

 

 ** data=(int **)malloc(m*sizeof(int *));
    for(i=0;i<m;i++)
        data=(int *)malloc(n*sizeof(int));  
 
Τι λαθος κανω ?

 

Στην ουσία το [][] δεν ξέρει τι είναι ο compiler. πρέπει να του βάλεις το πρώτο όρισμα ώστε να φτιάξει έναν πίνακα από δείκτες. Για να κάνεις αυτό που θες πρέπει να το ορίσεις ως int ** data; και να προχωρήσεις στην αρχική malloc στο data = malloc() και μετά όπως το κάνεις..

Δημοσ. (επεξεργασμένο)

Υπάρχουν δύο τρόποι για να φτιάξεις έναν δυναμικό MxN πίνακα σε C:

α) δέσμευση διανύσματος μεγέθους MxN και κατάλληλη προσπέλαση.

β) δέσμευση διανύσματος μεγέθους Μ από pointers σε διανύσματα μεγέθους Ν.

 

Εγώ προτιμώ πάντα τον α) τρόπο, που είναι κι αυτός που υπέδειξε ο/η Anubis13.

Εσύ πας με το β) και μπερδεύεσαι.

 

Έστω ότι θέλεις να φτιάξεις ένας ΜxN από integers:

int **matrix = malloc(M * sizeof(int *));
for (int i = 0; i < N; i++) {
    *(matrix + i) = malloc(N * sizeof(int));
}

// the same as...

int **matrix = NULL;

matrix = malloc(M * sizeof(int *));
for (int i = 0; i < N; i++) {
    *(matrix + i) = malloc(N * sizeof(int));
}

Το λάθος που έκανες εσύ είναι πως πήγες να αναθέσεις κάποια τιμή σε μνήμη που

δεν είχες δεσμέυσει. Δήλωσες το data ως δείκτη σε δείκτη και πήγες να αναθέσεις

κάποια τιμή στα περιεχόμενα του δείκτη σε δείκτη σε ακέραιο. Για να το κάνεις αυτό

(το οποίο θα αντιστοιχεί στην πρώτη θέση του πίνακα) πρέπει πρώτα να δεσμεύσεις

χώρο στη μνήμη.

 

Έστω πως εσύ είχες δεσμεύσει χώρο για δείκτη σε δείκτη σε ακέραιο. Πας και αναθέτεις

σε ακέραιο, κάτι που είναι τύπου δείκτη σε δείκτη σε ακέραιο (διεύθυνση). Έχεις θέμα πάλι.

Επεξ/σία από gon1332
  • Like 2
Δημοσ.

Να τονίσω αυτό που θίχτηκε από πάνω:
 

lala a[][];

είναι διαφορετικό πράγμα από

lala **b;

και θα περίμενα να μην κάνει καν compile το πρώτο.

Δημοσ.

Να τονίσω αυτό που θίχτηκε από πάνω:

 

lala a[][];

είναι διαφορετικό πράγμα από

lala **b;

και θα περίμενα να μην κάνει καν compile το πρώτο.

Σε ποια περίπτωση θα περίμενες να μην κάνει καν compile το πρώτο;

 

Πάντως ισχύει ότι αυτά τα δύο είναι διαφορετικά, αν δεσμεύσεις μνήμη για το δεύτερο.

Δημοσ.

Πιστεύω πως τα παρακάτω 2 links θα σε βοηθήσουν να ξεκαθαρίσεις τι παίζει με τους δείκτες, τους στατικούς πίνακες και τους δυναμικούς πίνακες:

 

1. Arrays in C

2. comp.lang.c FAQ - Question 6.16

 

Την πιο απλή διαχείριση μνήμης την επιτυγχάνεις κάνοντας allocate μονοκόμματα NROWS * NCOLS στοιχεία, με κόστος την ελαφρώς πιο σύνθετη προσπέλαση, μιας και στην ουσία έχεις μονοδιάστατο πίνακα (μπορείς να χρησιμοποιήσεις όμως ένα macro, π.χ. IDX(i,j) που βελτιώνει και το readability και την χρήση). Βασικά, αυτό ακριβώς συμβαίνει "από κάτω" όταν ορίζεις στατικό 2Δ πίνακα (γίνεται allocate μονοκόμματα ως 1Δ, και όπου γράφεις εσύ "array[j]" αυτό μετατρέπεται αυτόματα σε "array[i*NCOLS+j]").

 

Ο κώδικας που ακολουθεί σε spoiler είναι ένα τέτοιο παράδειγμα ενός δυναμικού 1Δ πίνακα, ο οποίος όμως χρησιμοποιείται ως 2Δ. Παρατήρησε πόσο απλή είναι η διαχείριση μνήμης του (δηλαδή το malloc() και το free() του). Παρατήρησε επίσης ότι μπορείς να τον προσπελάσεις σαν να ήταν 2Δ, με τη βοήθεια του IDX() macro (δες το population loop). Στο printing loop η προσπέλαση γίνεται κανονικά με έναν indexer i (αντί για δυο, i και j) αλλά και πάλι χρησιμοποιείται η NCOLS για να τυπωθεί αλλαγή γραμμής μετά από κάθε row.

 

 

#include <stdio.h>
#include <stdlib.h>

#define NROWS        3
#define NCOLS        4
#define IDX(i,j)     ((i) * NCOLS + (j))

/*********************************//**
 *
 *************************************
 */
int main( void )
{
	int i,j;

	// allocate memory
	int *arr2d = malloc( NROWS * NCOLS * sizeof(int) );
	if ( NULL == arr2d ) {
		fprintf( stderr, "malloc() failed, bye...\n" );
		exit(1);
	}

	// populate the array, traversing it via IDX(i,j)
	for (i=0; i < NROWS; i++) {
		for (j=0; j < NCOLS; j++) {
			arr2d[ IDX(i,j) ] = IDX(i,j);
		}
	}

	// print the array, traversing it normally
	const int NELEMS = NROWS * NCOLS;
	for (i=0; i < NELEMS; i++) {
		if ( 0 == i % NCOLS ) {
			putchar( '\n' );
		}
		printf( "%02d ", arr2d[i] );
	}
	putchar( '\n' );
	
	// release used memory
	free( arr2d );

	exit(0);
}

 

Ο ίδιος κώδικας προσαρμοσμένος ώστε να χρησιμοποιεί 2Δ δυναμικό πίνακα (όπως δηλαδή προσπαθείς να το κάνεις εσύ) έχει ως αποτέλεσμα ελαφρώς πιο απλή προσπέλαση του πίνακα, αλλά αρκετά πιο σύνθετη διαχείριση μνήμης:

 

 

#include <stdio.h>
#include <stdlib.h>

#define NROWS        3
#define NCOLS        4

/*********************************//**
 *
 *************************************
 */
int main( void )
{
	int i,j;

	// allocate memory
	int **arr2d = malloc( NROWS * sizeof(int *) );
	if ( NULL == arr2d ) {
		goto malloc_failed;
	}
	for (i=0; i < NROWS; i++) {
		arr2d[i] = malloc( NCOLS * sizeof(int) );
		if ( NULL == arr2d[i] ) {
			for (j=0; j < i; j++) {
				free( arr2d[j] );
			}
			free( arr2d );
			goto malloc_failed;
		}
	}

	// populate the array
	for (i=0; i < NROWS; i++) {
		for (j=0; j < NCOLS; j++) {
			arr2d[i][j] = i * NCOLS + j;
		}
	}

	// print the array
	for (i=0; i < NROWS; i++) {
		for (j=0; j < NCOLS; j++) {
			printf( "%02d ", arr2d[i][j] );
		}
		putchar( '\n' );
	}
	
	// release used memory
	for (i=0; i < NROWS; i++) {
		free( arr2d[i] );
	}
	free( arr2d );

	exit(0);

malloc_failed:
	fprintf( stderr, "malloc() failed, bye...\n" );
	exit(1);
}

 

  • Like 1

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...