Taille de tableau ?

Signaler
Messages postés
9
Date d'inscription
mardi 1 mars 2005
Statut
Membre
Dernière intervention
13 février 2007
-
Messages postés
9
Date d'inscription
mardi 1 mars 2005
Statut
Membre
Dernière intervention
13 février 2007
-
Bonjour à tous

Je suis sur un projet vc++ v6 dans lequel je manipule des images. J'ai
fait un petit algo qui permet de récupérer des coordonnées de pixels
intéressants d'une image et de les stocker dans un int*. J'ajoute les 2
coordonnées grace à une fonction Add_pix() qui réalloue dynamiquement
la mémoire (realloc). Ca marche très bien jusqu'à une certaine taille
de mon tableau. Genre vers 6000 pixels (soit 12000 coordonnées) il met
l'erreur "Unhandled exception in X.exe : acces violation" en mode
debug. Bon ca fait 12000*2 = 24 ko, ca me semble po insurmontable
mais peut etre que je me trompe (surement même vu que ca ne marche pas
!) L'erreur vient quand je remplie mon tableau, juste après avoir
réalloué la mémoire. (J'ai essayé avec un POINT * et c'est exactement
le même problème).



Alors je voulais savoir est ce que c'est un problème de limite de la taille mémoire ou comment faire autrement ??

Merci d'avance

8 réponses

Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
Met un peu de code ça aidera à cerner le problème en particulier la fonction qui alloue et realloue et celle qui remplie. Il n'y a pas de limitation de mémoire à ce niveau (tu peux allouer plusieurs Mo sans problème).
Messages postés
9
Date d'inscription
mardi 1 mars 2005
Statut
Membre
Dernière intervention
13 février 2007

Note : nb_elt est le nombre de pixel de l'objet courant et p la liste de coordonnées appartenant à l'objet courant



void CObjet::Add_pixel(int *point)

{

p = (int *)realloc(p, (nb_elt*2+2)*sizeof(int));

*(p+(nb_elt*2)) = *(point+0);

*(p+(nb_elt*2)+1) = *(point+1);

nb_elt++;

}



Ca parait peut etre con de s'embeter avec un int* et un tableau de
coordonnées de point mais c'est la seule solution que j'ai trouvé ... :(
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
Cette fonction me parrait bonne mais pourrait être plus lisible :
void CObjet::Add_pixel(int *point)
{
p = (int *)realloc(p, (nb_elt*2+2)*sizeof(int));
p[nb_elt*2] = point[0];
p[nb_elt*2+1] = point[1];
nb_elt++;
}

Le plantage provient peut-être d'un écrasement mémoire (un pointeur mal utilisé ou un tableau où tu écrit hors de ses limites) qui corrompt le pointeur p.

Il serait peut être plus judicieux (si possible) d'allouer le tableau en une seule fois.
Messages postés
9
Date d'inscription
mardi 1 mars 2005
Statut
Membre
Dernière intervention
13 février 2007

Merci de ta réponse. C'est vrai que c'est un peu lourd ma notation et je vais vite changer ça.

Le problème c'est que je ne connais pas la taille totale (elle augmente au fur et a mesure du parcours de l'image).

C'est chaud à trouver ça un écrasement mémoire, parcequ'il me met aucune erreur ou warning. Ya un moyen pour détecter ça ?
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
pas vraiment à moins de faire du pas à pas sur ton prog et vérifier l'adresse mémoire pointée par p. Une solution est également de faires des tests systématiques sur les indices de tableaux.
Messages postés
9
Date d'inscription
mardi 1 mars 2005
Statut
Membre
Dernière intervention
13 février 2007

Euh ... je viens de voir compte que je remplie toujours le meme CObjet
qui est, de surcroit en variable globale. Ca, Je suis obligé.

En fait j'ai un tableau de Cobjet pict2[] et la fonction etale renvoie
un Cobjet correctement remplie. Cet objet, c'est justement celui qui
est en variable globale.



while(c pas fini)

{

pict2[cpt] = etale(x, y);

cpt++;

}



Est ce qu'il faudrait pas que je fasse un delete juste après l'appel à
etale ? Vu que c'est assez obscure pour moi ces histoires de delete,
qu'est ce qu'il faut mettre dans le destructeur ? En fait il faudrait
juste supprimer le pointeur p (un int *) associé à l'objet non?
Messages postés
402
Date d'inscription
mardi 1 mai 2001
Statut
Membre
Dernière intervention
15 août 2011

Personnellement, je te conseillerais d'utiliser un second pointeur avec realloc()

int * ptr = realloc( p, ... );

if ( NULL == ptr )
{
perror("realloc()");
return;
}

p = ptr;
*(p ...) = ...;

realloc() peu très bien échouer et s'il échoue tu pers ta mémoire/pointeur => p
Au fait, *(p + 0) == *p

Le delete ca dépend, si tu veux garder ton objet il ne faut pas faire de delete tout de suite, si tu as besoin de ton/tes objet(s) => pas de delete, seulement lorsque tu en as plus besoin.
Si tu as un array d'objet par exemple:

OBJ arr[size];
arr[0] = new OBJ;
arr[1] = new OBJ;

avant de remettre quelque chose dans `arr[0]` il faudrat supprimer ce qui si trouve:

delete arr[0];
arr[0] = new OBJ;

etc ...

Ton calcule n'est pas bon => 12000*2 = 24 ko
Ce serait plutôt: 12000*2 *sizeof(int) = 93,75kB

Ton problème/erreur te dis simplement que tu vas `jouer` ou tu n'a pas le droit => access violation ... Vérifie tes pointeurs

Toute allocation, libération, ... de mémoire doit être valider:

type * variable = allocation_memoire(...);
if ( NULL == variable )
{
ERROR
}

...
...

if ( NULL != variable )
{
liberation_memoire( variable );
variable = NULL;
}

~(.:: NitRic ::.)~
Messages postés
9
Date d'inscription
mardi 1 mars 2005
Statut
Membre
Dernière intervention
13 février 2007

Ok merci bien, je vais faire tout ce que vous me conseillez (test pour realloc et vérifier l'adresse de mon pointeur).