0
この問題の説明方法が正確にわかりません。それは非常にランダムです。Cアレイの質問 - 再割り当てされたメモリでの奇妙なメモリの問題
私はここに掲載いくつかのコード持っている: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であるが)。テストコードは配列内の新しいスロットへのポインタを追加しているため、割り当てを解除してから再度実行します。
奇妙なことは、if文が明らかにそうであってはならない場合、mainの配列(array2)の2番目のテストで真と評価されるということです。
私は完全に明白な何かを見逃しているに違いない - あるいは私が気づいていないヒープ/スタックで起こっている奇妙なものがあります。
アイデア?
私は行47を次のように変更しました。memset(cmpcm、0、(total - array-> total)* array-> size); – gngrwzrd