我不知道如何解释这个问题。这是非常随意的。
我在这里发布了一些代码: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;
}
问题出在第54行。从技术上讲,不应该根据main()中的测试代码输入if语句。因为测试代码正在向数组中的新插槽添加指针,解除分配并再次执行。
奇怪的是,if语句在main中对数组(array2)的第二次测试的评估结果是真的,当它明显不应该是。
我必须遗漏一些完全明显的东西 - 或者我不知道堆/堆上有一些奇怪的东西。
有什么想法吗?
答案 0 :(得分:0)
我相信我明白了。在realloc之后我的memset只清除n个字节,当它应该清除n * size字节时。