English 中文(简体)
valgrind 8 大小无效读数
原标题:valgrind Invalid read of size 8
  • 时间:2012-05-21 23:15:11
  •  标签:
  • c
  • valgrind

I m trying to understand why Valgrind reports a "Invalid read of size 4" error. Code compile and give correct output on Linux console.
The goal is to build a dynamic array of struct record(up to 10Mil items) that grow dynamically and organize its by language through the struct list.

守则:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include "../crc64.c"

typedef struct {
  char          cat;
  uint64_t      crc;
  int           id;
} record;

typedef struct {
  int           count;
  char          *lang;
  record        **records;
} list;

record *records = NULL;
int record_count = 0;
list *lists = NULL;
int list_count = 0;

void addItemToList(record *r, char *lang){  
  int found = 0;
  for(int i = 0; i<list_count; i++){
    if(strcmp(lists[i].lang, lang) == 0){
      list *l = &lists[i];
      found = 1;      
      record **tmp  = realloc(l->records, (l->count + 1) * sizeof(record *));
      if (tmp == NULL)
        printf("Problem on realloc - records/list
");
      else{
        l->records = tmp;
        l->count ++;
        l->records[l->count -1] = r;
      }        
      break;
    }
  }
  if(found == 0){
    list_count ++;
    list *tmp = realloc(lists, list_count  * sizeof(list));
    if(!tmp) 
      printf("Error on realloc - list");
    lists = tmp;
    lists[list_count - 1].count =1 ;
    lists[list_count - 1].lang = lang ;
    record **tmp1 = realloc(NULL, sizeof(record *));
    if(!tmp1)
      printf("Error on realloc records/list 
");          
    lists[list_count - 1].records = tmp1;      
    tmp1[0] = r;    
  }  
}

int addRecord(char cat, char *name, int id, char lang[3]){  
  record *tmp;
  if(record_count == 0){
    tmp = malloc(1 * sizeof(record));         
  }  
  else 
    tmp = realloc(records, (record_count + 1)  * sizeof(record));
  if(tmp == NULL){
    printf("Error on m(re)alloc records
");
    return(1);
  }  

  records = tmp;
  record r = {cat, crc64(name), id};
  records[record_count ] = r; 
  addItemToList(&(records[record_count]), lang);
  record_count ++;
  return 0;  
}

int main(void){
  addRecord( l , "torino",1, "it");
  addRecord( l , "berlin",20, "de");
  addRecord( l , "paris",30, "fr");  
  addRecord( l , "hamburg",21, "de");
  addRecord( l , "sassari",2, "it");
  addRecord( l , "cagliari",3, "it");
  addRecord( l , "milano",4, "it");


  for(int i=0; i< list_count;i++){
    printf("lang: %s, count :%d
", lists[i].lang, lists[i].count);  
    for (int z = 0; z < lists[i].count; z ++){
      printf("  crc:  %lu -   id: %d 
", lists[i].records[z]->crc, lists[i].records[z]->id);
    }
  }
  return 0;
}

Valgrind 这里的输出 :

cc -std=c99  -O0 -g tt.c -o tt && valgrind --track-origins=yes ./tt
lang: it, count :4
==17435== Invalid read of size 4
==17435==    at 0x400BAC: main (tt.c:92)
==17435==  Address 0x51d0050 is 16 bytes inside a block of size 24 free d
==17435==    at 0x4C29097: realloc (vg_replace_malloc.c:525)
==17435==    by 0x400990: addRecord (tt.c:65)
==17435==    by 0x400A8E: main (tt.c:81)
==17435== 
==17435== Invalid read of size 8
==17435==    at 0x400BE0: main (tt.c:92)
==17435==  Address 0x51d0048 is 8 bytes inside a block of size 24 free d
==17435==    at 0x4C29097: realloc (vg_replace_malloc.c:525)
==17435==    by 0x400990: addRecord (tt.c:65)
==17435==    by 0x400A8E: main (tt.c:81)
==17435== 
  crc:  10540480176773849829 -   id: 1 
  crc:  5100567372334599520 -   id: 2 
  crc:  16805344662159858020 -   id: 3 
  crc:  16314500525507880138 -   id: 4 
lang: de, count :2
  crc:  3766391767329109829 -   id: 20 
  crc:  12127946872667643737 -   id: 21 
lang: fr, count :1
  crc:  2180538375615994033 -   id: 30 
问题回答

您正在重新定位记录, 但您不更新指示器 。

tmp = realloc(records, (record_count + 1)  * sizeof(record));

当您这样做时, 旧 < code> records 数组的所有指针都变成 < 强度 > 无效 。

仅举一个简单的例子。

record *array = malloc(sizeof(*array));
record *r1 = &array[0];
array = realloc(array, sizeof(*array) * 2);
record *r2 = &array[1];
// r1 is probably invalid, since  array  changed

有一些方法你可以解决这个问题。

  1. reallec 时,通过并更新所有指针。这是一个真正的痛苦。

  2. 将每个记录单独分类, 而不是在一个大数组中 。 (否, 这将浪费内存 。 至少不会与每个记录中由于字段顺序已经浪费的8 字节相比 。)

  3. 而非记录指针, 请在记录矩阵中使用索引。 这些不需要更新 。





相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签