- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图理解为什么 Valgrind 报告“大小 4 的无效读取”错误。代码编译并在 Linux 控制台上给出正确的输出。
目标是构建一个动态数组结构 record(最多 1000 万个项目),动态增长并通过结构 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\n");
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 \n");
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\n");
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\n", lists[i].lang, lists[i].count);
for (int z = 0; z < lists[i].count; z ++){
printf(" crc: %lu - id: %d \n", 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));
执行此操作时,所有指向旧 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
有几种方法可以解决这个问题。
当您重新分配
时,遍历并更新所有指针。这是一个真正的痛苦。
单独分配每条记录,而不是在一个大数组中。 (不,这不会浪费内存。至少与由于字段顺序已经浪费的每条记录 8 字节相比不会。)
不使用指向记录的指针,而是使用记录数组中的索引。这些不需要更新。
关于c - valgrind 大小为 8 的无效读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10693827/
我希望 valgrind 在发现第一个错误时停止并退出。 请勿推荐 --vgdb-error=1 :它不会退出 valgrind。您必须连接 gdb 并从那里终止。 --db-attach : 在最近
有人可以快速解释 Valgrind 的工作原理吗?一个例子:它如何知道内存何时被分配和释放? 最佳答案 Valgrind 基本上在“沙箱”中运行您的应用程序。在此沙箱中运行时,它能够插入自己的指令来进
我有一个因 SIGSEGV 而崩溃的应用程序。 --20183-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) -
我有一个因 SIGSEGV 而崩溃的应用程序。 --20183-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) -
我想使用 valgrind 检查长时间运行的进程是否存在内存泄漏。我怀疑我所追求的内存泄漏可能仅在执行几个小时后才会发生。我可以在 valgrind 下运行应用程序并获取 valgrind 日志,但这
我想用 valgrind 检查一个长时间运行的进程是否有内存泄漏。我怀疑我所追求的内存泄漏可能仅在执行数小时后才会发生。我可以在 valgrind 下运行应用程序并获得 valgrind 日志,但这样
如何在不通过 valgrind 命令选项启动它的情况下对每个 Process 实例执行 valgrind memcheck。 有没有办法将监控选项保存在进程中,而不是每次都使用 valgrind 命令
我使用了“--trace-children=yes”选项,我还使用了“--trace-children-skip=patt1,patt2,...”选项(过滤掉噪音过程)。但它对我来说仍然很慢,我的多进
我从 Valgrind 得到以下日志: MPK ==5263== 4 bytes in 1 blocks are still reachable in loss record 1 of 84 ==52
如何在 Valgrind 抑制文件中添加注释? 我需要为一个大型项目维护一个 Valgrind 抑制文件。我们从我们链接到的工具中过滤无法修复的错误。随着工具的新版本发布,此文件可能需要随着时间的推移
我有一个大程序要运行。使用 valgrind 需要几个小时才能运行。我听说有一些东西可以让我们为程序中的特定函数调用 valgrind。其余程序将正常执行(没有 valgrind env)。 任何人都
我可以用 valgrind 检测整数溢出缺陷吗?里面的哪个工具可以做到这一点? 最佳答案 Valgrind 没有可以检测整数溢出的工具。 您可能会使用 gcc 选项捕获这些错误: -ftrapv Th
我有一个简单的程序: int main(void) { const char sname[]="xxx"; sem_t *pSemaphor; if ((pSemaphor = sem_o
如何让 Valgrind 准确显示错误发生的位置?我编译了我的程序(通过 PuTTy 在 Windows 机器上通过 Linux 终端)添加了 -g 调试选项。 当我运行 Valgrind 时,我得到
或者最好是全部,而不仅仅是我的代码?我的程序使用 Gtk、Loudmouth 和其他一些东西,而这两个(以及它们背后的一些,libgcrypto、libssl)本身导致了如此多的错误,以至于我无法检测
我想尝试使用 valgrind 进行一些堆损坏检测。通过以下腐败“单元测试”: #include #include #include int main() { char * c = (ch
我看过类似的问题here ,但我的问题是我没有编辑 default.supp 文件的权限。例如,Valgrind 中是否有任何忽略所有抑制文件的命令行选项? 最佳答案 在 Valgrind 3.10.
我在一个运行无限循环的程序上使用 valgrind。 由于memcheck在程序结束后显示内存泄漏,但由于我的程序有无限循环,它永远不会结束。 那么有什么方法可以强制从 valgrind 时不时地转储
我一直在尝试使用 valgrind 查找一些可疑的内存错误。 在被分析的程序甚至到达我希望分析的点之前,它会因为对 mmap 的调用开始失败而退出。当它不在 valgrind 下时,这些调用会成功。
由于 OpenSSL 使用未初始化的内存,因此对使用 openldap2 的 libldap 的程序进行 Valgrind 是一件苦差事。存在一个 --ignore-fn选项,但仅适用于 Valgri
我是一名优秀的程序员,十分优秀!