Je développe une structure de rangée juste pour l'amusement. Cette structure, généralisée par un paramètre de template, permet d'allouer un nombre donné d'éléments au démarrage, puis, si les items "busy" sont plus nombreux que ceux disponibles, une fonction réallouera le buffer interne. Le code de test est:Comportement étrange de realloc
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
template <typename T> struct darray_t {
size_t items;
size_t busy;
T *data;
};
#define DARRAY_REALLOC_ITEMS_STEP 10
#define da_size(da) (da)->busy
template <typename T>
void da_init(darray_t<T> *da, size_t prealloc){
da->items = prealloc;
da->busy = 0;
da->data = (T *)malloc(sizeof(T) * prealloc);
}
template <typename T> T *da_next(darray_t<T> *da){
if(da->busy >= da->items){
da->data = (T *)realloc(da->data, sizeof(T) * DARRAY_REALLOC_ITEMS_STEP);
da->items += DARRAY_REALLOC_ITEMS_STEP;
}
return &da->data[ da->busy++ ];
}
int main(){
darray_t<int> vi;
int *n;
da_init(&vi, 100);
for(int i = 0; i < 101; ++i){
n = da_next(&vi);
*n = i;
}
for(int i = 0; i < da_size(&vi); ++i){
if(vi.data[i] != i){
printf("!!! %d != %d\n", i, vi.data[i]);
}
}
return 0;
}
Comme vous pouvez le voir, je prealloc 100 pointeurs entiers au début, puis je les réallouer avec 10 autres pointeurs à la fois. Dans la fonction principale, j'effectue une boucle for pour vérifier l'intégrité des éléments et, si un élément de tableau n'est pas conforme à mes attentes, j'imprime sa valeur et ... vous savez quoi? J'ai le message suivant:
!!! 11! = 135121
En fait, l'élément à l'index 11, qui devrait être '11', est 135121 !!!! : S
Pouvez-vous me dire si mon code n'est pas correct?
Merci
NOTE Je sais parfaitement que le mélange C et C++ de cette manière est laid, et je sais aussi que cette structure bousiller si elle est utilisée, par exemple:
darray_t<std::string>
Ceci est juste un test pour les pointeurs int.
Ugh, C avec des modèles, ce qu'est un mélange laid. (Que pensez-vous qu'il se passera si j'instancie votre modèle avec 'std :: string'?) – sbi
Je sais, c'est juste un test! :) –
Cette structure n'est pas destinée à être utilisée avec des classes, évidemment dans ce cas je devrais utiliser new operator pour alloc (pour appeler la classe ctor) et je ne pourrais pas utiliser le realloc. Mais je le répète, ce n'est qu'un test pour les pointeurs int. –