gpt4 book ai didi

c - valgrind 发现无效写入和读取的数量令人难以置信

转载 作者:行者123 更新时间:2023-11-30 14:57:13 25 4
gpt4 key购买 nike

作为 valgrind 新手,我试图理解为什么 valgrind 在我的一个 C 程序中发现大量无效写入和读取。它首先报告函数调用的无效写入,其中指向数组的调用指针以及数组本身,我认为已在 main 中分配了适当的内存。更令人费解的是,它继续反对该函数中的许多行,其中声明的 double 被赋值。

我的 C 程序根据实验数据完善(即改进)肌肉的横桥循环模型(微小蛋白质马达与另一种蛋白质的细丝反复相互作用以产生力和运动的事件循环)。该程序通过基于下坡单纯形法的模拟退火进行,所需的函数取自 C 中的数值配方。

每个模型由 19 个参数定义,x[1] 到 x[19]。通过首先将 x 声明为指向 double 的指针,然后创建一个编号从 1 到 19 的数组,在 main 中为该数组分配内存。

double *x;
x=dvector(1,19);

然后为 19 个参数分配值,最初是根据猜测,然后使用基于之前历史记录的算法:

for (j=1;j<=19;j++)
{
x[j]=initial_guess;
}

然后将指向 x 数组的指针传递给函数 Scoremodel,该函数以多种方式测试模型的机械性能,每种方式都会生成一个分数,并且加权平均分数 y 在第 629 行传回 main:

y=scoremodel(x);

我的程序第932行的scoremodel声明是

double scoremodel(double *x)

(我也尝试过

double scoremodel(double x[])

但与 valgrind 的结果是相同的)

Main 然后根据之前的结果和下坡单纯形/模拟退火算法计算出下一步应该测试什么新模型。

在我在 Stack Overflow 上发表最后一篇文章后,在 Mark Setchell 的大力帮助下,我现在已经能够使用 gcc-4.9 和 –fopenmp 标志编译我的程序,以便我可以在我的 MacPro 上使用 OpenMP 运行它使用 Yosemite OS x 10.10.5 运行)。它运行时不会崩溃或挂起。大多数连续模型的属性和分数都是完全合理的,仅考虑这些,程序确实显着地改进了起始模型。但奇怪的是,大约五分之一的模型具有荒谬的属性和非常差的分数。

我使用以下命令调用了当前版本的 valgrind 来检测程序的较短测试版本(名为finemadpmodelinc2)中的内存错误

 valgrind-3.12.0/bin/valgrind --leak-check=yes ${HOME}/bin  /refinemadpmodelinc2 inc2_49 model3 model4 0 0.9 20 ../../tls/kappaFHStrunc

Valgrind 报告程序中的第一个错误发生在我声明函数 Scoremodel 的行处。

Invalid write of size 8
==33173== at 0x100001F71: scoremodel (refinemadpmodelinc2.c:932)
==33173== by 0x100001D8A: main (refinemadpmodelinc2.c:629)
==33173== Address 0x1045029a8 is on thread 1's stack
==33173== in frame #0, created by scoremodel (refinemadpmodelinc2.c:932)

我认为大小为 8 的无效写入是由于我试图写入一个 double 型或指向不可用内存的指针而引起的,因为它们的大小在我的计算机上都是 8 字节。但我不明白我的函数调用出了什么问题。

函数中接下来的一百行,几乎所有变量声明,都由 valgrind 传递,但从第 1109 行到第 1203 行,每个非空白行都被认为是大小为 8 的无效写入,尽管这些行中的大多数是只是简单的作业,例如

exppower=395.9;

(当 exppower 已声明为 double 时)。我的预感是,虽然我在调用函数 Scoremodel 时犯了错误并扰乱了 valgrind,但这些行肯定没问题。非常感谢您帮助我了解 valgrind 的奥秘。

最佳答案

在这种情况下,Valgrind 不太可能是错误的。

旧版本的“数值配方”对从 1 到 大小(含)的数组使用 Fortran 约定,在 C 和 C++ 中分配额外的未使用的元素。本书的最新版本(第三版,仅限 C++)已经废除了所有基于 1 的数组内容(尽管它距离如何编写 C++ 的光辉示例还很远)。然而,如果您使用基于 0 的数组混合数值配方和任何形式的更传统的 C 或 C++,这仍然是一个陷阱。

关于c - valgrind 发现无效写入和读取的数量令人难以置信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44072530/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com