Comment remettre à zéro les nouvelles de la mémoire après le realloc
Quel est le meilleur moyen de remettre à zéro les nouvelles de la mémoire après l'appel de realloc tout en gardant le initialement alloué de la mémoire intacte?
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
size_t COLORCOUNT = 4;
typedef struct rgb_t {
int r;
int g;
int b;
} rgb_t;
rgb_t** colors;
void addColor(size_t i, int r, int g, int b) {
rgb_t* color;
if (i >= COLORCOUNT) {
//new memory wont be NULL
colors = realloc(colors, sizeof(rgb_t*) * i);
//something messy like this...
//memset(colors[COLORCOUNT-1],0 ,sizeof(rgb_t*) * (i - COLORCOUNT - 1));
//...or just do this (EDIT)
for (j=COLORCOUNT; j<i; j++) {
colors[j] = NULL;
}
COLORCOUNT = i;
}
color = malloc(sizeof(rgb_t));
color->r = r;
color->g = g;
color->b = b;
colors[i] = color;
}
void freeColors() {
size_t i;
for (i=0; i<COLORCOUNT; i++) {
printf("%x\n", colors[i]);
//can't do this if memory isn't NULL
//if (colors[i])
// free(colors[i]);
}
}
int main() {
colors = malloc(sizeof(rgb_t*) * COLORCOUNT);
memset(colors,0,sizeof(rgb_t*) * COLORCOUNT);
addColor(0, 255, 0, 0);
addColor(3, 255, 255, 0);
addColor(7, 0, 255, 0);
freeColors();
getchar();
}
Cela a très de la mauvaise performance, quand une couleur est ajouté à la fin de la liste des couleurs, l'habitude d'appels. Vous n'aurez qu'à ajouter un élément à la fois avant réaffectation des. Tenir compte d'au moins l'allocation de max(i+1, décompte des couleurs * 2).
C'est juste un exemple pour illustrer le problème. La source est une table de hachage qui redimensionne par le premier numéro de l'IIRC
C'est juste un exemple pour illustrer le problème. La source est une table de hachage qui redimensionne par le premier numéro de l'IIRC
OriginalL'auteur Nick Van Brunt | 2010-01-26
Vous devez vous connecter pour publier un commentaire.
Il n'y a probablement pas besoin de faire la
memset
: vous ne pouvez pas utilisercolors[k]
avant de le mettre avec quelque chose de valable plus tard. Par exemple, votre code définitcolors[i]
nouvellement allouécolor
pointeur, donc, vous n'avez pas besoin de définircolors[i]
àNULL
.Mais, même si vous avez voulu "zéro de telle sorte tout est beau", ou vraiment besoin d'une nouvelle pointeurs être
NULL
: la norme ne garantit pas que tous les bits à zéro est le pointeur null constante (c'est à dire,NULL
), de sortememset()
n'est pas la bonne solution de toute façon.Le seul portable que vous pouvez faire est de régler le pointeur de
NULL
dans une boucle:Votre principal problème, c'est que votre
realloc()
appel est erroné.realloc()
retourne un pointeur vers le redimensionnement de la mémoire, il n'est pas (nécessairement) la redimensionner en place.Donc, vous devriez faire:
Si vous voulez vraiment savoir ce que l'
memset()
appel devrait être, vous avez besoin de mettre à zéro la mémoire commençant àcolors+COLORCOUNT
, et de définiri+1-COLORCOUNT
membres à zéro:Mais comme je l'ai dit ci-dessus, tous les octets à zéro n'est pas garanti d'être un
NULL
pointeur, de sorte que votrememset()
est inutile de toute façon. Vous devez utiliser une boucle si vous souhaitezNULL
pointeurs.Dire qu'en supposant que la valeur NULL == 0 est "inutile" est un peu exagéré. Même si il n'est pas explicitement requis par la norme, c'est le cas dans tous connus du compilateur C que je suis au courant. En outre, il peut accélérer de façon significative bug squashing à utiliser calloc ou memset à force de mauvaises lectures. Je serais plutôt d'appliquer NULL == 0 via
assert(NULL == 0)
au début du programme que d'écrire des tonnes de complexe et bizarre code pour prendre en charge qu'une application aléatoire qui choisit autre chose.OriginalL'auteur Alok Singhal
Il n'y a aucun moyen de résoudre cela comme une tendance générale. La raison en est que, afin de savoir quelle partie de la mémoire tampon qui est nouveau, vous avez besoin de savoir combien de temps l'ancien tampon a été. Il n'est pas possible de déterminer, dans C et donc empêche une solution générale.
Cependant, vous pourriez écrire un wrapper comme
OriginalL'auteur JaredPar
Tout d'abord, realloc peut échouer, donc vous devez vérifier la valeur NULL. Deuxièmement, il n'y a pas de meilleure façon de remettre à zéro la mémoire: il suffit de memset à partir de la fin de l'ancien tampon à la fin de la mémoire tampon plus importante.
on dirait que vous êtes de passage de la valeur au couleurs[décompte des couleurs-1] pour être réaffectée, plutôt qu'un pointeur vers cet emplacement.
realloc peut ne pas être en mesure de réaffecter en place et sera de retour d'un nouveau pointeur. Vous devriez vérifier et mettre à jour la couleur avec la nouvelle valeur si elle n'est pas NULL. C'est pour cela que le code peut échouer. L'autre raison peut être que realloc ne pouvais pas allouer plus de mémoire (il a retourné NULL de vous dire cela, mais de les jeter).
Tous les octets à zéro peut ou peut ne pas être un pointeur null constante. Voir ma réponse pour plus de détails.
OriginalL'auteur florin
Écrire votre propre fonction, dire
reallocz
, qui accepte la taille actuelle en tant que paramètre, et les appelsrealloc
etmemset
pour vous. Il vraiment de ne pas obtenir beaucoup mieux que ce que vous avez déjà... c'est du C, après tout.OriginalL'auteur Thomas