Valgrind在While循环开始时显示无效读数

时间:2016-10-08 10:43:01

标签: c memory-leaks valgrind

我在while循环的比较器行上显示了无效读取错误。奇怪的是我检查了底部循环比较器中使用的变量,它们在那里很好,但是当while循环在顶部比较它们时它们无效地读取。它们必须发生在循环底部和顶部之间,但我不知道是什么。

这是包含故障循环的函数:

void keyMatch(Block * Buff, Key key, int * buff_fill, int * Buff_size){
    int k = 0;
printf("k:%i buff fill:%i, then %i\n",k,*buff_fill,(k)<(*buff_fill));fflush(stdout);
    while((k)<(*buff_fill)){
        if(block_addable(key,Buff[k])){
            bufadd(Buff,key,k,buff_fill,Buff_size);
            }
        k++;
        printf("k:%i ",k);fflush(stdout);
        printf("buff fill:%i",*buff_fill);fflush(stdout);
        printf("then %i\n",(k)<(*buff_fill));fflush(stdout);
    }
    printf("done\n");fflush(stdout);
}

这是增加* buff_fill的函数:

void bufadd(Block * Buff , Key key,int buff_index, int * buff_fill, int * Buff_size){
    if(*buff_fill==(*Buff_size)){
        Buff = (Block*) realloc(Buff,2*(*Buff_size)*sizeof(Block));
        (*Buff_size) =(*Buff_size)*2;
    }

    Buff[*buff_fill]=Buff[buff_index];
    Buff[*buff_fill].Keys[Buff[*buff_fill].fill]=key;
    Buff[*buff_fill].fill++;
   (*buff_fill)=(*buff_fill)+1;

}

这是Valgrind内存检查器的一段显示无效读取:

k: 0 buff fill: 26, then 1
k: 1 buff fill: 27 then 1
k: 2 buff fill: 28 then 1
k: 3 buff fill: 29 then 1 ==
3845 == Invalid read of size 8 ==
3845 == at 0x4013B0: keyMatch(main.c: 225) ==
3845 == by 0x40167D: getBlocks(main.c: 260) ==
3845 == by 0x400A1B: main(main.c: 362) ==
3845 == Address 0x83d6130 is 240 bytes inside a block of size 2, 240 free 'd ==
3845 == at 0x4C2DEAE: realloc( in /usr/lib / valgrind / vgpreload_memcheck - amd64 - linux.so) ==
3845 == by 0x4012BF: bufadd(main.c: 198) ==
3845 == by 0x401452: keyMatch(main.c: 227) ==
3845 == by 0x40167D: getBlocks(main.c: 260) ==
3845 == by 0x400A1B: main(main.c: 362) ==
3845 ==

以下是c代码的其余部分,但我不相信它与此问题相关:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
//#include <omp.h>
#include <math.h>

double dia = 0.000001;

typedef struct {
    long ID;
    float value;
}Key;

Key ** Keys;

typedef struct {
    int fill;
    long signature;
    Key Keys[4];
}Block;

typedef struct{
    long signture;
    Block * Blocks;
}Group;

//Function used as a tool in getExpectedBlocks to help determine the maximum possible ammount of block
 unsigned long long nChoosek( unsigned n, unsigned k ){
    if (k > n) return 0;
    if (k * 2 > n) k = n-k;
    if (k == 0) return 1;

    unsigned long long result = n;
    for( int i = 2; i <= k; ++i ) {
        result *= (n-i+1);
        result /= i;
    }
    return result;
}

//Finds the most probable ammount of Blocks in the database, value is used for memory allocation
int getExpectedBlocks(int rows){
double largest = 0;

    for(int i =1 ; i < 4 ; i++){
    double size = nChoosek(rows,i+1);
        for (int j = 0 ; j < i ; j++){
        size *= (2*dia);
        }
        if(size>largest){
        largest=size;

        }
    }
return largest;
}

//Gets the dimensions of the database and obviously the keys as well, mainly used for memopry allocation
int * getDimensions(){
int * dimensions = (int*) calloc(2, sizeof(int));
dimensions[0]=0;
dimensions[1]=0;

FILE *fp;
  if ((fp = fopen("data.txt","r")) != NULL)
    {
            int rows=0;
            int numbers=0;
            char c;
            while((c=fgetc(fp))!=EOF){
                if(c=='\n'){
                rows++;
                }
                if((c=='\n')||(c==',')){
                numbers++;
                }
            }
            dimensions[0]=rows;
            dimensions[1]=numbers/rows;
    }
    else{
    printf("data.txt failed to open");
        exit(1);
    }
  fclose(fp);

return dimensions;
}

//Get an array of doubles containing all the rowIDs
long * getIDs(int rows){
  FILE *fp;
  long *rowIDs;
  if ((fp = fopen("keys.txt","r")) != NULL)
    {
    //Allocate memory for all the rowIDs
    rowIDs = (long*) calloc(rows, sizeof(long));

    //Fill rowIDs with the actual IDs
        char c;
        int ID_pos = 0;
        int rowIDs_index = 0;
        char ID[15]="";
        //char * p;
        while((c=fgetc(fp))!=EOF){
            if(isdigit(c)){
            ID[ID_pos]=c;
            ID_pos++;
            }
            if(ID_pos==14){
            rowIDs[rowIDs_index]=atol(ID);
            rowIDs_index++;
            strcpy(ID,"00000000000000");
            ID_pos=0;
            }
        }

    }
    else{
    printf("keys.txt failed to open");
        exit(1);
    }

  fclose(fp);
  return rowIDs;
}

//Get a 2D array of floats containing all keys in their respective columns
float ** getValues(int rows, int columns){
 FILE *fp;
  float **Values;
  if ((fp = fopen("data.txt","r")) != NULL)
    {
    //Allocate memory for all the Values
    Values = (float**)calloc(columns, sizeof(float*));
    for(int i = 0; i < columns; i++) {

    Values[i] = (float*)calloc(rows, sizeof(float));
    }

    //Fill Values with the actual Values
        char c;
        int value_pos = 0;
        int row_index = 0;
        int column_index = 0;
        char value[9]="";
        char * p;
        while((c=fgetc(fp))!=EOF){

            if((isdigit(c))||(c=='.')){
            value[value_pos]=c;
            value_pos++;
            }

            if(!((isdigit(c))||(c=='.'))&&(c!=13)){
            Values[column_index][row_index]=strtof(value,&p);
            column_index++;
            strcpy(value,"00000000");
            value_pos=0;
            }

            if(c=='\n'){
            column_index=0;
            row_index++;
            }
        }

    }
    else{
    printf("data.txt failed to open");
        exit(1);
    }

  fclose(fp);
  return Values;
}

Key ** makeDatabase(long * rowIDs, float ** Values, int rows, int columns){
    Key ** Keys = (Key**)calloc(columns, sizeof(Key*));
        for(int i = 0; i < columns; i++) {
            Keys[i] = (Key*)calloc(rows, sizeof(Key));
        }

    for(int col = 0 ; col < columns ; col++){
        for(int row = 0 ; row < rows ; row++){
        Keys[col][row].ID= rowIDs[row];
        Keys[col][row].value=Values[col][row];
        }
    }

return Keys;
}

void bufadd(Block * Buff , Key key,int buff_index, int * buff_fill, int * Buff_size){
    if(*buff_fill==(*Buff_size)){
        Buff = (Block*) realloc(Buff,2*(*Buff_size)*sizeof(Block));
        (*Buff_size) =(*Buff_size)*2;
    }

    Buff[*buff_fill]=Buff[buff_index];
    Buff[*buff_fill].Keys[Buff[*buff_fill].fill]=key;
    Buff[*buff_fill].fill++;
   (*buff_fill)=(*buff_fill)+1;

}

int block_addable(Key addkey, Block block){
    if(block.fill>3){
        return 0;
    }
    for(int i = 0 ; i < block.fill ; i++){
        if(block.Keys[i].ID==addkey.ID){
        return 0;
        }
    }
    return 1;

}

void keyMatch(Block * Buff, Key key, int * buff_fill, int * Buff_size){
    int k = 0;
printf("k:%i buff fill:%i, then %i\n",k,*buff_fill,(k)<(*buff_fill));fflush(stdout);
    while((k)<(*buff_fill)){
        if(block_addable(key,Buff[k])){
            bufadd(Buff,key,k,buff_fill,Buff_size);
            }
        k++;
        printf("k:%i ",k);fflush(stdout);
        printf("buff fill:%i",*buff_fill);fflush(stdout);
        printf("then %i\n",(k)<(*buff_fill));fflush(stdout);
    }
    printf("done\n");fflush(stdout);
}

Block * getBlocks(Key * column, int ExpectedBlocks, int rows, int * blocks){

    Block * Blocks = (Block*)calloc(ExpectedBlocks, sizeof(Block));
    int Blocks_size = ExpectedBlocks;

    //Buff = realloc(Buff,ExpectedBlocks*sizeof(Block));
    int Buff_size = ExpectedBlocks;
    int * buff_fill = malloc(sizeof(int));
    *buff_fill=0;

    for(int i = 0; i < rows ; i++){
        Block * Buff = (Block*)calloc(ExpectedBlocks, sizeof(Block));
        //add the 'self' block to the possible blocks buff
        Buff[0].Keys[0]=column[i];
        Buff[0].fill=1;
        *buff_fill=1;

        //check if the next key is in neighborhood


        int j = i+1;
        while((j<rows)&&((fabsf(column[i].value-column[j].value))<dia)){
            //add match to possible blocks buffer
            keyMatch(Buff,column[j],buff_fill,&Buff_size);
            j++;
        }

        for(int j = 0; j < *buff_fill ; j++){
           // printf("%i Buff No. %i  ",i,j);
                for(int x = 0 ; x < Buff[j].fill ; x++){
                  //  printf("%f ",Buff[j].Keys[x].value);
                    }
                  //  printf("\n");
        }

        //clear buffer whilst extracting full blocks
        for(int j = 0 ; j <*buff_fill ; j++){
            //add full blocks to blocks
            if(Buff[j].fill==4){
                //check if Block is large enough for the values being added and expands if neccessary
                if(*blocks==(Blocks_size)){
                    //printf("block realloc during %i in... %i/%i..",i,*blocks,Blocks_size);fflush(stdout);
                    Blocks =(Block*) realloc(Blocks,2*Blocks_size*sizeof(Block));
                    //printf("out\n");fflush(stdout);
                    Blocks_size=2*Blocks_size;
                }
                //printf("block adding during %i in... %i/%i..",i,*blocks,Blocks_size);fflush(stdout);
                Blocks[*blocks]=Buff[j];
                (*blocks)=(*blocks)+1;
                //printf("out\n");fflush(stdout);
            }
            //Buff[j].fill=0;


         }

         //printf("begi in %i ...",i);fflush(stdout);
         free(Buff);
         //rintf("done\n");fflush(stdout);
    }
    return Blocks;
}

int cmpkeys(const void *a, const void *b){
const Key* ka = (Key*)a;
const Key* kb = (Key*)b;
  return (ka->value > kb->value) - (ka->value < kb->value);
}

void setsignatures(Block * Blocks,int blocks){
    for(int i = 0 ; i < blocks ; i++){
        long sig = 0;
        for(int j = 0 ; j <4 ; j++){
            sig += Blocks[i].Keys[j].ID;
        }
        Blocks[i].signature=sig;
    }
}

Group * getGroups(Block ** AllBlocks){
    Group * Groups;

    return Groups;
}

int main(){
float fudgefactor = 1.5;


//Determine how many dimensions for preallocation of memory
    int * dimensions = getDimensions();
    int rows = dimensions[0];
    int columns = dimensions[1];
//Load the RowIDs into an Array
    long * rowIDs = getIDs(rows);

//Load the Keys into an Array
   float ** Values =getValues(rows,columns);

//Generate database of all Keys
    Keys = makeDatabase(rowIDs,Values,rows,columns);
    //printf("first value is %f",Keys[0][0].value);

    free(Values);
    free(rowIDs);

    Block ** AllBlocks = (Block**)calloc(columns, sizeof(Key*));

//Determine Expected number of blocks per column for predictable memory allocation
    int ExpectedBlocks = fudgefactor*getExpectedBlocks(rows);

//this array stores the number of blocks in each column
    int * blocks = (int*)calloc(columns, sizeof(int));
//IN parallel, organise then find the blocks in the columns
    int i;
//#pragma omp parallel for
    for(i=0  ; i < columns; i++){
         qsort(Keys[i],rows,sizeof(Key),cmpkeys);
    }
//#pragma omp parallel for
    for(i=0  ; i < columns; i++){
    //Sort Keys by values Database for easier search pattern
        //Search for and list blocks in Keys[i]
        printf("column:%i\n",i);
        int blocks=0;
        Block * Blocks = getBlocks(Keys[i],ExpectedBlocks,rows,&blocks);
        setsignatures(Blocks,blocks);
        AllBlocks[i]= Blocks;
        for(int j = 0; j < blocks ; j++){
            printf("%i Blocks No. %i  ",i,j);
                for(int x = 0 ; x < 4 ; x++){
                    printf("%f ",Blocks[j].Keys[x].value);
                    }
                    printf("\n");
        }
    }

    //Put all Blocks in Groups
    //Group * Groups = getGroups(AllBlocks);

    return 0;
}

0 个答案:

没有答案