Question

J'écris une application en C en utilisant l'API win32. Lorsque je tente d'agrandir la taille de mon tableau, en utilisant la fonction HeapRealloc (), il change mes valeurs actuelles du tableau, au lieu de les copier. Le code que j'utiliser pour réallouer la mémoire:

BOOL ChangeFeedArraySize(UINT newSize)
{   
    char tempChar[20] = "";
    PFEED tempArr;
    if (newSize == 1)
    {
        tempArr = (PFEED)HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(FEED));
    }
    else
    {
        tempArr = (PFEED)HeapReAlloc(heap, HEAP_ZERO_MEMORY, categoryArray, newSize * sizeof(FEED));
        // FEED - a struct
        // PFEED - a pointer to the struct
        // categoryArray - array to be reallocated
    }

    if (tempArr != NULL)
    {
        MessageBox(NULL, ltoa(HeapSize(heap, 0, tempArr),tempChar,10) , "Heap size after reallocation", MB_OK | MB_ICONEXCLAMATION);
        feedArray = tempArr;
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

Voici l'état des tableaux quand en point d'arrêt. le réseau d'alimentation indique l'état de réseau en cours. le tableau de température montrent le nouvel état du tableau réaffectés (ce qui est différent).

array aliments:

feedArray http://www.freeimagehosting.net/uploads/526b0b2172.jpg

réseau de temp:

TempArray http://www.freeimagehosting.net/uploads/17858f2e7e.jpg

S'il vous plaît aider ..: \

Lien vers la description de fonction MSDN

Était-ce utile?

La solution

Vous citez une fonction spécifique sous Windows, mais cela est vrai aussi de realloc(), qui est la norme équivalente.

Si ces fonctions renvoient la même adresse que transmis, c'est parce que la mémoire juste après le tampon que vous avez demandé est à l'origine utilisé. Ainsi, il peut répondre à la demande sans déplacer le tampon.

Mais s'il y avait deux allocations rapides en succession immédiate, par exemple? Peut-être la mémoire juste après ce qui a été demandé à l'origine a fini par être utilisé pour l'attribution suivante. Dans ce cas, l'allocateur doit trouver de l'espace ailleurs, copier ce qui était dans le vieux tampon, libérer l'ancien tampon, et retourner le nouveau.

En général, le modèle que vous voulez suivre pour ce genre de chose est comme ceci:

void *newmem = realloc(oldmem, newsize);
if (!newmem)
{
   // TODO: handle failure
   // possibly free(oldmem); depending on how you want to handle errors
}
else
{
   oldmem = newmem;
}

Un raccourci commun est que les gens prennent « oldmem = realloc(oldmem, newsize); », mais ce n'est pas aussi gracieuse que ci-dessus, comme il fuit oldmem quand il y a un échec.

Mise à jour en fonction de votre édition :

Une chose que je me demande dans votre code est cette partie:

if (newSize == 1)
{
    tempArr = (PFEED)HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(FEED));
}

Cela semble supposer que la première allocation sera toujours de la taille d'un. Etes-vous sûr que vous ne pas dire if (feedArray == NULL), puis allouer newSize * sizeof(FEED)?

Deuxième mise à jour:

OK. L'autre chose qui se démarque est la suivante:

    tempArr = (PFEED)HeapReAlloc(heap, HEAP_ZERO_MEMORY, categoryArray,
                                 newSize * sizeof(FEED));
    // Snip...

    if (tempArr != NULL)
    {
        // Snip...
        feedArray = tempArr;

Les parties doivent être bolded même.

Autres conseils

De la documentation, je vois que:

HeapReAlloc est garanti pour préserver le contenu de la mémoire étant réaffecté, même si la nouvelle mémoire est allouée à un autre endroit. Le processus de préservation du contenu de la mémoire implique une opération de copie de mémoire qui est potentiellement beaucoup de temps.

Donc la question suivante serait comment voulez-vous venir à la conclusion que le contenu du tableau ont changé? Pourriez-vous fournir le code? Il est possible qu'il pourrait y avoir des problèmes de pointeur impliqués et / ou des hypothèses sur l'endroit où les pointeurs existants pointent maintenant (il est important de supposer que l'appel du système d'exploitation est correct et complètement épuiser toute possibilité votre code d'application pourrait être en faute d'abord parce que, tout en bugs peuvent exister avec un appel du système d'exploitation, il est probable qu'un bug avec une fonction aussi importante que cela aurait été remarqué avant).

Après l'appel à la HeapReAlloc de sorte que vous ne possédez plus, il a été libéré tabCatégories d'origine. D'autres allocations peuvent réutiliser a d'autres fins et le contenu peuvent ont changé. Vous devez utiliser le tempArr désormais:

tempArr = (PFEED)HeapReAlloc(heap, HEAP_ZERO_MEMORY, categoryArray, newSize * sizeof(FEED)); 
cetagoryArray = tempArr;

où vous cherchez après un appel à HeapRealloc? vous devriez regarder dans le RETOURNER pointeur, pas celui d'origine qui a été libéré par après votre appel

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top