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

Πρόβλημα με malloc σε C


clevercitizen

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

Δημοσ.

Καλημέρα.

Θέλω να δημιουργήσω έναν μονοδιάστατο πίνακα ακεραίων Ν θέσεων, το Ν θα δίνεται από το χρήστη, χρησιμοποιώντας malloc, και θα δίνουμε τιμές στον πίνακα.(σε C και όχι σε c++)

 

#include <stdio.h>

#include <stdlib.h>

 

int main()

{

int N,i;

int A[N];

int *p;

 

printf("Doste to n");

scanf("%d",&N);

 

p=malloc(N*sizeof(int*));

if (p==NULL)

{printf("ERROR");

exit(1);}

 

p=A;

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

{printf("Dose arithmo");

scanf("%d",&A);}

free(p);

return 0;

}

Το πρόγραμμα δε λειτουργεί:(

Νομίζω ότι δεν έχω καταλάβει καλά τη malloc, οπότε θα ήθελα τα φώτα σας.

Ευχαριστώ.

Δημοσ.

Εφόσον καλείς malloc και αναθέτεις στο p, το p είναι ο πίνακάς σου.

 

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

int main()
{
    int N,i;
    // Σημείο 1: Δε χρειάζεσαι A[N].
    int *p;

    printf("Doste to n: ");
    scanf("%d",&N);

    p=(int*)malloc(N*sizeof(int*));
    if (p==NULL)
    {
       printf("ERROR");
       exit(1);
    }

    // Σημείο 2: Δεν αναθέτεις το A στο p γιατί τότε "χάνεις" το p.
    for(i=0;i<N;i++)
    {
       printf("Dose arithmo: ");
       scanf("%d",&p[i]); // Σημείο 3: Χρησιμοποιείς το p ως πίνακα.
    }

    free(p);
    return 0;
}

Δημοσ.

τσεκαρε και αυτο

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

int main(int argc, char* argv[])
{

size_t IntSz = sizeof(int);
   //allocate a int
int *ptrInt = (int*) malloc(IntSz);
//(int*) convert void pointer to int pointer
//add data 
ptrInt[0] = 12312;

//allocate 2 int
int *ptr2Int = (int*) malloc(IntSz * 2);
//add data
ptr2Int[0] = 123123;
ptr2Int[1] = 435342;


//clean
free(ptrInt);
free(ptr2Int);



return 0;
}

Δημοσ.
Εφόσον καλείς malloc και αναθέτεις στο p, το p είναι ο πίνακάς σου.

 

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

int main()
{
    int N,i;
    // Σημείο 1: Δε χρειάζεσαι A[N].
    int *p;

    printf("Doste to n: ");
    scanf("%d",&N);

    p=(int*)malloc(N*sizeof(int*));
    if (p==NULL)
    {
       printf("ERROR");
       exit(1);
    }

    // Σημείο 2: Δεν αναθέτεις το A στο p γιατί τότε "χάνεις" το p.
    for(i=0;i<N;i++)
    {
       printf("Dose arithmo: ");
       scanf("%d",&p[i]); // Σημείο 3: Χρησιμοποιείς το p ως πίνακα.
    }

    free(p);
    return 0;
}

 

.

.

.

.

printf("Doste to n");

scanf("%d",&N);

 

p=malloc(N*sizeof(int*));

if (p==NULL)

{printf("error mnimis");

exit(1);}

 

srand((long) 220234);

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

{scanf("%d", &p);

 

}

.

.

.

.

Ακριβώς αυτό έχω κάνει και εγώ αλλά ρωτάω αν είναι λάθος το Α[Ν] που έχω ορίσει αρχικά και μετά κάνω p=Α, δηλ ο δείκτης p να δείχνει στον πίνακα Α. Γίνεται κάτι τέτοιο ή αποκλειστικά η malloc δεσμεύει το χώρο που θέλουμε μόνο για το δείκτη(αλλά ο Α είναι ο ταυτόχρονα και δείκτης του πίνακα Α[Ν])?

Έχω δοκιμάσει επίσης αντί τoυ p να βάλω Α, έχοντας ορίσει τον πίνακα Α, Ν στοιχείων (int A[N] και μετά A=malloc() κτλ), αλλά απ ότι θυμάμαι δε μου δούλεψε....

Δημοσ.
.

Ακριβώς αυτό έχω κάνει και εγώ αλλά ρωτάω αν είναι λάθος το Α[Ν] που έχω ορίσει αρχικά και μετά κάνω p=Α, δηλ ο δείκτης p να δείχνει στον πίνακα Α. Γίνεται κάτι τέτοιο ή αποκλειστικά η malloc δεσμεύει το χώρο που θέλουμε μόνο για το δείκτη(αλλά ο Α είναι ο ταυτόχρονα και δείκτης του πίνακα Α[Ν])?

Έχω δοκιμάσει επίσης αντί τoυ p να βάλω Α, έχοντας ορίσει τον πίνακα Α, Ν στοιχείων (int A[N] και μετά A=malloc() κτλ), αλλά απ ότι θυμάμαι δε μου δούλεψε....

 

Όχι δεν έχεις κάνει αυτό. Ο κώδικας σου είναι ένδειξη του πόσο μπερδεμένος είσαι.

 

το int A[N] δεσμεύει μνήμη. Όμως:

α) το Ν δεν έχει οριστεί (έχει τυχαία τιμή) -> άρα είναι λογικό λάθος

β) η μνημη προερχεται απο το stack -> δεν πειράζει για μικρά N, σε μεγάλα δεν συνηστατε

c) μόνο στο τελευταίο πρότυπο προβλέπετε δέσμευση άγνωστης ποσότητας μνήμης απο το stack (το N είναι άγνωστο κατα τη διαρκεια του compile) -> ίσως δεν παίζει παντού (με όλους τους compilers).

 

οταν κάνεις p = malloc, δεσμεύεις μνήμη για τον πίνακα που θες (αυτός είναι ο σωστός τρόπος) και μετά κάνεις το μεγάλο λάθος

 

p = A. Εδω διαγράφεις την παλια τιμή της p (που ήταν η μνήμη που είχες δεσμευσει με malloc) και βάζεις την p να δείχνει στον τυχαίας διάστασης πίνακα A.

Φυσικά δεν μπορείς τώρα να κάνεις free(p) γιατι το p δεν έχει δεσμευτεί με malloc.

 

ανακαιφαλαίωση: Το int Α[Ν] είναι δέσμευση χώρου για πίνακα

To p = malloc(N * sizeof int] είναι δέσμευση χωρου για πίνακα

Μην τα μπερδευεις μεταξύ τους είναι σχεδόν ισοδύναμα, απλά αλλου χρησιμοποιούμε το ένα και αλλού το άλλο. ΟΧΙ και τα δυο μαζί.

Δημοσ.

Βασικα πρεπει να καταλαβεις οτι η καθε δηλωση εκτος απο τη τιμη εχει και κατι αλλο απο "πισω", γνωστο ως δεικτης (pointer).

Δηλαδη το "int a = 0" εκτος οτι κουβαλαει το "0" μαζι του, εχει και ενα δεικτης . Για να δεις τον δεκτη θελεις αυτο το συμβολο "&". Ενα δεικτη μπορεις να τον "αποθηκευσεις" σε "void*" κατι τετοιο "void* pa = &a". Το pa τωρα ειναι μια τιμη, δηλαδη το pa εινα διφορο του a "pa!=a". Εφοσον το pa ειναι μια τιμη, μπορεις να την μετατρεψεις σε ενα αλλο τυπο με την προυποθεση οτι ξερεις το μεγεθος του δεικτη στο συστημα που εισαι, πχ για 32bit συστηματα μπορεις να το μετατρεψεις σε κατι που αποτελειται(η υπερβαλει) απο 32 bit, αρα μπορεις να τον μετατρεψεις σε int "int ia = (int)pa". Τωρα εχεις δυο int το"a" και το "ia" τα οποια ειναι διαφορα μεταξυ τους, και ας προερχονται απο το a.:shock:

 

Αυτο που λενε πινακα ([]) εγω το λεω τροπο αναγνωσης τηε μνημης ( γιατι ειμαι χομπιστας B)). Δηλαδη το "int Ints[2]=..." ειναι ενας δεικτης, με τη δηλωση του int [] ζητας; ο επομενος δεικτη να ειναι συν 4 θεσεις (θεσεις=μεγεθος του τυπου που θελεις σε byte)μπροστα(μπροστα/πισω,4 θεσεις 10 θεσεις... εξαρτατε απο το συστημα). in code

 

>	int a[2] = {7,8};
void* pa = a;
printf("o deyteros ariumos einai:%d\n",a[1]);
printf("o deyteros ariumos einai:%d\n",*(a+1));
printf("o deyteros ariumos einai:%d\n",*((int*)((int)pa+4)));//32bit sys

 

 

 

Η συναρτηση "void* malloc(size_t size)"

size:Το μεγεθος σε byte που θελεις

επιστρεφει: ενα δεικτη, αν ειναι "NULL" error mpla mpla

 

αρα θελεις δυο πραματα.

Α) Ενα τυπο (θελεις int)

Β) Και ενα μεγεθος (Ν*sizeof(int) ή για 32bit sys Ν*4)

>	
#include <stdlib.h>

int main(int argc, char* argv[])
{
int N=9;
   int* pint = (int*)malloc(N*sizeof(int));
   //add data
for(int i=0;i<N;i++)
  pint[i]=rand();
//ή *(pint+i) = rand();

//getdata
for(int i=0;i<N;i++)
	printf("%d\n",pint[i]);
//ή printf("%d\n",*(pint+i));
free(pint);
getchar();


return 0;
}


B)

 

 

Υγ Οτνα καλεις την sizeof(int*) στην ουσια περνεις το μεγεθος του pointer που ειναι 4, βγαλε το αστερισκο, οτι και να βαλεις με αστερισκο θα σου επιστρεφει 4... sizeof(char*) = sizeof(int*)= sizeof(long*)=sizeof(somesturct*)

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...