Domanda

Io non esattamente so come spiegare questo problema. E 'estremamente casuale.

Ho un po 'di codice postato qui: http://pastebin.com/d2vzas5S

#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <assert.h>

char * s1 = "hello";

struct gdarray {
    ssize_t idx;
    size_t incr;
    size_t total;
    size_t used;
    size_t size;
    void * flex;
};
typedef struct gdarray gdarray;

gdarray * gdarray_create(size_t size, size_t incr) {
    gdarray * array = calloc(1,sizeof(gdarray));
    array->idx = -1;
    array->used = 0;
    array->total = incr;
    array->incr = incr;
    array->size = size;
    array->flex = calloc(incr,size);
    return array;
}

void gdarray_add_pntr(gdarray * array, void * pntr) {
    if(!array || !array->flex) return;
    size_t total = array->total;
    ssize_t idx = array->idx+1;
    ssize_t idx_1 = idx+1;
    void ** flex = array->flex;
    if(total < idx_1) {
        total = idx+array->incr;
        void * tmp = realloc(array->flex,array->size * total);
        if(!tmp) {
            perror("gdarray_add_pntr.!tmp");
            return;
        }
        char * cmpcm = (char *)&((char **)tmp)[idx];
        memset(cmpcm,0,(total - array->total) - 1);
        array->flex = tmp;
        array->total = total;
        flex = tmp;
    }
    if(array->used < idx_1) array->used = idx_1;
    array->idx = idx;
    if(flex[idx]) {
        printf("this should never get called!\n");
        //free(flex[idx]); - this free needs to happen ONLY if there is
        //indeed a pointer at flex[idx] - but this branch is entered
        //randomly it seems - I can't figure out why this branch is
        //entered
    }
    flex[idx] = pntr;
}

void gdarray_dealloc(gdarray * array, bool free_array,
    bool free_flex, bool free_entries)
{
    if(free_entries) {
        size_t i = 0;
        size_t c = array->used;
        void ** flex = (void **)array->flex;
        for(;i<c;i++) if(flex[i]) free(flex[i]);
    }
    if(free_flex) free(array->flex);
    if(free_array) free(array);
}

int main(int argc, char ** argv) {
    gdarray * array = gdarray_create(sizeof(char *),4);
    gdarray_add_pntr(array,strdup(s1));
    gdarray_add_pntr(array,strdup(s1));
    gdarray_add_pntr(array,strdup(s1));
    gdarray_add_pntr(array,strdup(s1));
    gdarray_add_pntr(array,strdup(s1));
    gdarray_add_pntr(array,strdup(s1));
    gdarray_add_pntr(array,strdup(s1));
    gdarray_add_pntr(array,strdup(s1));
    gdarray_dealloc(array,true,true,true);

    gdarray * array2 = gdarray_create(sizeof(char *),2);
    gdarray_add_pntr(array2,strdup(s1));
    gdarray_add_pntr(array2,strdup(s1));
    gdarray_add_pntr(array2,strdup(s1));
    gdarray_add_pntr(array2,strdup(s1));
    gdarray_dealloc(array2,true,true,true);
    return 0;
}

Il problema è alla riga 54. Tecnicamente l'istruzione if non dovrebbe mai essere inserito in base al codice di prova in main (). Poiché il codice di prova è l'aggiunta di puntatori a nuovi slot nella matrice, deallocing, e facendo di nuovo.

Cosa c'è di strano è che l'istruzione if sta valutando su true per la seconda prova della matrice (array2) nella principale quando chiaramente non dovrebbe essere.

Devo mancare qualcosa di completamente ovvio -. O Ci sono alcune cose strane in corso con l'heap / stack che io non sono a conoscenza di

Tutte le idee?

È stato utile?

Soluzione

Credo ho preso. la mia memset dopo il realloc stava solo schiarendo n byte, quando dovrebbe di stato compensazione n * size byte.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top