开发者

C Array Question - Strange memory issue with realloc'd memory

I don't exactly know how to explain this problem. It's extremely random.

I've got some code posted here: 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 s开发者_高级运维hould 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;
}

The problem is at line 54. Technically the if statement shouldn't ever be entered based on the test code in main(). Because the test code is adding pointers to new slots in the array, deallocing, and doing it again.

What's strange is that the if statement is evaluating to true for the second test of the array (array2) in main when it clearly shouldn't be.

I must be missing something completely obvious - or there's some strange stuff going on with the heap / stack that I'm not aware of.

Any ideas?


I believe I got it. my memset after the realloc was only clearing n bytes, when it should of been clearing n*size bytes.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜