2010-05-26 9 views
2

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.

+1

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

+0

Je sais, c'est juste un test! :) –

+0

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. –

Répondre

3

realloc ne développe pas automatiquement la mémoire - vous devrez le faire. Do .: par exemple

da->data=(T*)realloc(da->data, sizeof(T)*(da->items+DARRAY_REALLOC_ITEMS_STEP)); 

(et vous devez gérer realloc retourner NULL)

1

La taille du bloc est incorrect:

da->data = (T *)realloc(da->data, sizeof(T) * DARRAY_REALLOC_ITEMS_STEP); 

Le bloc entier est aussi grand que l'incrément. Essayez

da->busy + sizeof(T) * DARRAY_REALLOC_ITEMS_STEP