Problème avec les tableaux [C++] - Programmation
Marsh Posté le 21-06-2001 à 10:28:24
Salut,
Essaie de rajouter const aux paramètres de ta fonction, sinon dans ce le meiux c'est d'utiliser malloc. Bon personnellement je te recommande la deuxième solution.
@+
Archangel
Marsh Posté le 21-06-2001 à 11:04:26
c'est pour faire une allocation dynamique de la memoire !!!
Code :
|
Marsh Posté le 21-06-2001 à 11:11:33
en c++, on peut faire :
Code :
|
et ensuite dans ton programme tu fais (par exemple) :
BoolTab btab(x,y);
btab(0,0)= true;
if (btab(1,0)) fonction();
[edit]--Message édité par tgrx--[/edit]
Marsh Posté le 21-06-2001 à 11:44:07
Faudrait apprendre a darkoli la fonction calloc, parce que boucler dans le tableau pour tout mettre a zero quand ca peut tres bien etre fait a la creation, c'est pas optimal.
Perso, je ferais ainsi:
bool* p=(bool*)calloc(x*y,sizeof(bool));
if (!p)
return (-1);
//et tu utilises ca de la maniere suivante:
// la valeur tab[i][j] correspond a *(p+(i*y)+j)
// avec bien sur 0<=i<x et 0<=j<y
A+,
Marsh Posté le 21-06-2001 à 13:41:51
la difference entre calloc et malloc c'est quoi ?
svp ne m'insulter pas je n'ai pas forcement presenter un bout de code optimal, mais le but est plus de comprendre comment ca marche que tu file filer un truc optimale plus complexe a comprendre qu'on y connait pas grand chose.
Perso moi aussi je fais :
Code :
|
pour l'accés sa donne aussi : p[(j*y)+i]
attention pour l'acces il y a deux possibilité :
soit x colonne et y ligne : p[(j*x)+i]
soit x ligne et y colonne : p[(i*y)+j]
i e [0,x[, j e [0,y[
c'est pour ca que le tableau à deux dimension c'est bien quand tu n'as pas l'habitude parce sinon il fait faire tres attention.
Marsh Posté le 21-06-2001 à 20:28:49
Quand je lance mon programme, il y a une erreur disant que la mémoire ne peut être écrite.
Je pense que le problème vient de la manière dont je définis les différent valeur bool de mon tableau de bool:
#include <windows.h>
#include <iostream>
using namespace std;
///////////////////////////////////////////////////////////////////
class CBoolArray
{
int width;
int height;
public:
bool* bArray;
CBoolArray(int x, int y);
~CBoolArray() {delete [] bArray;}
bool& operator() (int x, int y) {return bArray[x+y*width];}
};
CBoolArray::CBoolArray(int x, int y)
{
width = x;
height = y;
bArray = new bool[width * height];
bArray = FALSE;
}
///////////////////////////////////////////////////////////////////
int CreateBitmask(const char szBitmap[], CBoolArray bMask, int width, int height, int rtrans,
int gtrans, int btrans)
{
HDC hdcImage;
HBITMAP hbm;
int pixelvalue = 0;
hbm = (HBITMAP) LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, width,
height, LR_CREATEDIBSECTION);
if (hbm == NULL)
hbm = (HBITMAP) LoadImage(NULL, szBitmap, IMAGE_BITMAP, width, height,
LR_LOADFROMFILE | LR_CREATEDIBSECTION);
hdcImage = CreateCompatibleDC(NULL);
SelectObject(hdcImage, hbm);
for (short y = 1; y <= height; y++)
{
for (short x = 1; x <= width; x++)
{
short r, g, b;
pixelvalue = GetPixel(hdcImage, x, y);
r = (pixelvalue & 0xFF);
g = (pixelvalue & 0xFF00)>>8;
b = (pixelvalue & 0xFF0000)>>16;
if (r != rtrans || g != gtrans || b != btrans)
bMask(x, y) = TRUE;
}
}
return 0;
}
///////////////////////////////////////////////////////////////////
int main()
{
CBoolArray BackgroundMask(1024, 768);
CreateBitmask("background.bmp", BackgroundMask, 1024, 768, 255, 0, 255);
if (BackgroundMask(50, 50) == TRUE)
cout << "TRUE" << endl;
else
cout << "FALSE" << endl;
while (1)
{
}
return 0;
}
Marsh Posté le 21-06-2001 à 20:51:40
y'a genre deux <= qu'il faudrait remplacer par des <
si tu veux faire clean, tu peux mettre une vérification de dépassement des valeurs du tableau qui n'est compilée que lorsque la constante DEBUG est définie pour éviter ce genre de prob dans le futur.
En général, il vaut mieux définir l'opérateur () deux fois
bool & operator() (int x, int y);
et
const bool & operator () (int x, int y) const;
la différence est que dans le deuxième cas, le résultat ne peut pas être une lvalue et est donc toléré pour les fonction prenant en paramètre un const CBoolTab &
enfin si tu trouves que 8 bits par bool, c'est trop, tu peux faire un tableau compact.
ie:
#include <vector>
using namespace std;
class BoolImage: public vector<bool>
{
int w,h;
public:
BoolImage(int tw=0, int th=0):w(tw), h(th), vector<bool>(tw*th){}
bool & operator () (int x, int y)
{ return operator[] (x+y*w);}
const bool & operator () (int x, int y)
{ return operator[] (x+y*w);}
};
et voilà
et avec cette classe tout marche, y compris
l'op =,
l'op ==,
l'op !=,
et les trucs de vector
Marsh Posté le 21-06-2001 à 20:53:35
pour être plus clair pour le bug:
x doit aller de 0 à <largeur et non de 1 à <=largeur
(idem pour y)
l'accès à des adresses au dlà donne une violation d'accès
(exc c000005?)
ou pire, un pernitieux effet de bord qui tue
Marsh Posté le 21-06-2001 à 21:50:01
darkoli a écrit a écrit : la difference entre calloc et malloc c'est quoi ? svp ne m'insulter. |
C'etait pas une insulte, j'ai pas dit Putain quel nain... Non, c'etait juste une remarque en passant, car calloc est trop souvent sous-employe, alors que c'est une fonction de base en C, tres pratique.
Les fonctions de base de gestion de la memoire en C sont:
malloc, calloc, realloc et free.
mettre un #include <stdlib.h> pour utiliser calloc.
prototype:
void *calloc(size_t nelem, size_t elsize);
parametres:
effet:
calloc alloue la memoire correspondante (une zone contigue), et initialise tous les bits de la zone allouee a 0.
retour:
En resume, calloc revient a effectuer un malloc puis a initialiser a 0 tous les bits de la zone allouee.
Les parametres de calloc sont un peu plus sympas que ceux de calloc pour allouer une table.
Le seul truc auquel il faut faire gaffe, c'est qu'il n'y a pas de fonction de base effectuant un recalloc (un realloc avec initialisation a 0 de la zone supplementaire allouee, s'il y a une telle zone).
A+,
[edit]--Message édité par gilou--[/edit]
Marsh Posté le 21-06-2001 à 22:12:03
gilou> Je me méfie beaucoup de realloc(), j'ai vu trop souvent d'implémentations foireuses. Quand je veux faire un realloc, je préfère le faire à la mano.
Par contre, calloc() est extrêmement utile, effectivement. A mon avis, il ne devrait même plus être recommandé, mais obligatoire quand on alloue une nouvelle chaîne de caractères (qui comme chacun sait doit se terminer par un caractère zéro, en C).
Et, au pire, darkoli, plutôt que de boucler sur ton buffer pour l'initialiser, utilise memset(), c'est plus efficace et aussi plus lisible qu'une boucle.
Marsh Posté le 21-06-2001 à 22:57:30
Bon j'ai modifié quelque truc, mais ça marche toujours pas... C'est la fonction Set de la classe CBoolArray qui merde je pense. Vous en pensez quoi?
#include <windows.h>
#include <iostream>
using namespace std;
///////////////////////////////////////////////////////////////////
class CBoolArray
{
int width;
int height;
public:
bool* bArray;
CBoolArray(int x, int y);
~CBoolArray() {delete [] bArray;}
Set(int x, int y, bool value);
bool& operator() (int x, int y) {return bArray[x+y*width];}
};
CBoolArray::CBoolArray(int x, int y)
{
width = x;
height = y;
bArray = new bool[width * height];
bArray = FALSE;
}
CBoolArray::Set(int x, int y, bool value)
{
bArray[x+y*width] = value;
return 0;
}
///////////////////////////////////////////////////////////////////
int CreateBitmask(const char szBitmap[], CBoolArray bMask, int width, int height, int rtrans,
int gtrans, int btrans)
{
HDC hdcImage;
HBITMAP hbm;
int pixelvalue = 0;
hbm = (HBITMAP) LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, width,
height, LR_CREATEDIBSECTION);
if (hbm == NULL)
hbm = (HBITMAP) LoadImage(NULL, szBitmap, IMAGE_BITMAP, width, height,
LR_LOADFROMFILE | LR_CREATEDIBSECTION);
hdcImage = CreateCompatibleDC(NULL);
SelectObject(hdcImage, hbm);
for (short y = 0; y < height; y++)
{
for (short x = 0; x < width; x++)
{
short r, g, b;
pixelvalue = GetPixel(hdcImage, x, y);
r = (pixelvalue & 0xFF);
g = (pixelvalue & 0xFF00)>>8;
b = (pixelvalue & 0xFF0000)>>16;
if (r != rtrans || g != gtrans || b != btrans)
bMask.Set(x, y, true);
}
}
return 0;
}
///////////////////////////////////////////////////////////////////
int main()
{
CBoolArray BackgroundMask(1024, 768);
CreateBitmask("background.bmp", BackgroundMask, 1024, 768, 255, 0, 255);
if (BackgroundMask(50, 50) == true)
cout << "TRUE" << endl;
else
cout << "FALSE" << endl;
while (1)
{
}
return 0;
}
[edit]--Message édité par Alload--[/edit]
Marsh Posté le 21-06-2001 à 23:02:17
tu comprends ce que tu tapes ?
bArray = new bool[width * height];
bArray = FALSE;
Marsh Posté le 21-06-2001 à 23:15:01
Oui c'est vrai que c'est pas malin... J'avais pas fait gaffe... Lol quel imbécile je suis déjà
Maintenant il arrive pas à lire avec le:
Background(50, 50);
Putain je vais pas y arriver à finir ce prog de merde...
Marsh Posté le 22-06-2001 à 00:01:08
BifaceMcLeOD a écrit a écrit : gilou> Je me méfie beaucoup de realloc(), j'ai vu trop souvent d'implémentations foireuses. Quand je veux faire un realloc, je préfère le faire à la mano. Par contre, calloc() est extrêmement utile, effectivement. A mon avis, il ne devrait même plus être recommandé, mais obligatoire quand on alloue une nouvelle chaîne de caractères (qui comme chacun sait doit se terminer par un caractère zéro, en C). Et, au pire, darkoli, plutôt que de boucler sur ton buffer pour l'initialiser, utilise memset(), c'est plus efficace et aussi plus lisible qu'une boucle. |
ok ok ben je vais utiliser calloc alors.
mais c'est vrai que pour realloc j'ai eu plein de merdes bizarre alors moi aussi je le fais à la main.
Marsh Posté le 22-06-2001 à 02:21:00
BifaceMcLeOD a écrit a écrit : gilou> Je me méfie beaucoup de realloc(), j'ai vu trop souvent d'implémentations foireuses. Quand je veux faire un realloc, je préfère le faire à la mano. |
Oui, oui, mon post etait la pour insister sur l'utilisation de calloc, pas sur celle de realloc.
A+,
Marsh Posté le 22-06-2001 à 09:50:51
Mais pourquoi ce que je veux ne peut pas être lu? La tableau a l'air d'être bien défini et j'extracte correctement les infos...
Marsh Posté le 21-06-2001 à 10:23:02
Je voudrais créer un tableau de bool en fonction de la taille x*y que donne l'utilisateur.
Pour cela j'emplois:
int Fonction(int x, int y)
{
bool bTableau[x][y];
}
Mais VC++ ne veut pas compiler car x et y ne sont constants. Comment faire alors un tableau de la bonne dimension?
[edit]--Message édité par Alload--[/edit]