Pour ce faire correctement, vous devez savoir au moins le nombre de lignes avant le redimensionnement. Une possibilité est de définir un struct
contenant des informations supplémentaires (genre d'approche POO, ont toutes les données pertinentes ensemble), comme dans l'exemple suivant (stockage aussi le nombre de colonnes, juste pour être complet, code non testé ici):
#include <stdlib.h>
#include <string.h>
typedef struct Lookup Lookup;
struct Lookup
{
size_t rows;
size_t cols;
char **data;
};
static void Lookup_destroy(Lookup *self)
{
if (!self) return;
for (size_t r = 0; r < self->rows; ++r)
{
free(self->data[r]);
}
free(self->data);
free(self);
}
static Lookup *Lookup_create(size_t rows, size_t cols)
{
Lookup *self = malloc(sizeof *self);
if (!self) return 0;
self->rows = rows;
self->cols = cols;
self->data = malloc(rows * sizeof *(self->data));
if (!self->data)
{
free(self);
return 0;
}
memset(self->data, 0, rows * sizeof *(self->data));
for (size_t r = 0; r < rows; ++r)
{
self->data[r] = malloc(cols * sizeof *(self->data[r]));
if (!self->data[r])
{
Lookup_destroy(self);
return 0;
}
}
return self;
}
static Lookup *Lookup_resize(Lookup *self, size_t rows, size_t cols)
{
if (!self) return Lookup_create(rows, cols);
// free rows that are no longer needed, if any:
for (size_t r = rows; r < self->rows; ++r)
{
free(self->data[r]);
self->data[r] = 0;
}
// reallocate array of rows:
char **newdata = realloc(self->data, rows * sizeof *newdata);
if (!newdata)
{
Lookup_destroy(self);
return 0;
}
// update row array and row count:
self->data = newdata;
size_t oldrows = self->rows;
self->rows = rows;
// initialize new rows to NULL, if any:
if (rows > oldrows)
{
memset(self->data + oldrows, 0,
(rows - oldrows) * sizeof *(self->data));
}
// reallocate individual rows:
for (size_t r = 0; r < rows; ++r)
{
char *newrow = realloc(self->data[r], cols * sizeof *newrow);
if (!newrow)
{
Lookup_destroy(self);
return 0;
}
self->data[r] = newrow;
}
// update col count:
self->cols = cols;
return self;
}
Notez comment le résultat de realloc()
est toujours stocké dans une variable temporaire d'abord, cela est nécessaire pour gérer correctement les erreurs. Ce code jette simplement tout l'objet en cas d'erreur - vous pouvez faire différentes choses avec plus de code bien sûr.
Vous pouvez l'utiliser dans votre code comme ceci:
int main(){
Lookup img;
img = Lookup_create(height, width);
// check for NULL here
img = Lookup_resize(img, height*2, width*2);
// and check for NULL here
}
Pour commencer, je vous recommande de faire des recherches sur * émulant passe par référence en c *. Pour continuer, quels seront les éléments * new * de 'img' après la réallocation? Astuce: ils sont * non initialisés * et ne peuvent être transmis tels quels à 'realloc'. Enfin, vous ne devriez jamais revenir au pointeur que vous passez à 'realloc', au cas où' realloc' échouerait. –
Ceci n'est pas ** un tableau 2d. Et la logique est imparfaite, d'abord 'free()' tableaux individuels qui ne sont plus nécessaires (le cas échéant), puis redimensionner votre tableau de pointeurs, puis allouer les tableaux individuels nouvellement nécessaires et redimensionner ceux qui étaient là avant. Et bien sûr, vérifiez les erreurs sur ** chaque ** 'appel malloc()'/'realloc()'. Enfin, modifier une variable locale modifie une ** copie **, vous devez par ex. retourner 'img' quand vous avez terminé. –
Et en général, "* mais cela ne fonctionne pas. *" ** n'est pas ** une description de problème appropriée. –