为什么 Valgrind 报告在 PETSc 中分配 char* 时大小为 8 的无效写入?
Why Valgrind reports an invalid write of size 8 on the assignment of a char* in PETSc?
我在 PETSc 中的应用程序终止错误。我检查了 Valgrind 的情况,但我不明白它的报告:
==97331== Invalid write of size 8
==97331== at 0x10007FED5: PetscHeaderCreate_Private (inherit.c:40)
==97331== by 0x1013EFE23: TSResilCreate (tsresil.c:525)
==97331== by 0x10139A877: TSGetResil (ts.c:5252)
==97331== by 0x10138D17E: TSSetFromOptions (ts.c:421)
==97331== by 0x100011A47: SolveODE (in ./ex31)
==97331== by 0x100012E98: main (in ./ex31)
==97331== Address 0x102dde080 is 1,776 bytes inside a block of size 1,780 alloc'd
==97331== at 0x100025EA1: malloc (vg_replace_malloc.c:303)
==97331== by 0x10010E8C1: PetscMallocAlign (mal.c:34)
==97331== by 0x10011063D: PetscTrMallocDefault (mtr.c:188)
==97331== by 0x1013EFDA0: TSResilCreate (tsresil.c:525)
==97331== by 0x10139A877: TSGetResil (ts.c:5252)
==97331== by 0x10138D17E: TSSetFromOptions (ts.c:421)
==97331== by 0x100011A47: SolveODE (in ./ex31)
==97331== by 0x100012E98: main (in ./ex31)
In tsresil.c:525(我在 PETSc 中的实现):
ierr = PetscHeaderCreate(resil,TSRESIL_CLASSID,"TSResil","Time stepping resilience","TS",comm,TSResilDestroy,TSResilView);CHKERRQ(ierr);
在inherit.c中:
22: /*
23: PetscHeaderCreate_Private - Creates a base PETSc object header and fills
24: in the default values. Called by the macro PetscHeaderCreate().
25: */
26: PetscErrorCode PetscHeaderCreate_Private(PetscObject h,PetscClassId classid,const char class_name[],const char descr[],const char mansec[],
27: MPI_Comm comm,PetscObjectDestroyFunction destroy,PetscObjectViewFunction view)
28: {
29: static PetscInt idcnt = 1;
30: PetscErrorCode ierr;
31: #if defined(PETSC_USE_LOG)
32: PetscObject *newPetscObjects;
33: PetscInt newPetscObjectsMaxCounts,i;
34: #endif
37: h->classid = classid;
38: h->type = 0;
39: h->class_name = (char*)class_name;
40: h->description = (char*)descr;
41: h->mansec = (char*)mansec;
...
PetscObject 是指向以下内容的指针:
typedef struct _p_PetscObject {
...
char *class_name; /* for example, "Vec" */
char *description;
...
因此,问题似乎与char* descr
的赋值有关,但我不明白为什么。大小 8 会通知指针错误,不是吗?
看起来 Valgrind 正在抱怨,因为您只为 PetscObject 分配了 1780 字节,而这 8 字节的写入(从字节 1776 开始)足以写入您没有分配的内存。
您需要增加分配的大小,或增加结构的大小,具体取决于分配的完整定义和方法。
我在 PETSc 中的应用程序终止错误。我检查了 Valgrind 的情况,但我不明白它的报告:
==97331== Invalid write of size 8
==97331== at 0x10007FED5: PetscHeaderCreate_Private (inherit.c:40)
==97331== by 0x1013EFE23: TSResilCreate (tsresil.c:525)
==97331== by 0x10139A877: TSGetResil (ts.c:5252)
==97331== by 0x10138D17E: TSSetFromOptions (ts.c:421)
==97331== by 0x100011A47: SolveODE (in ./ex31)
==97331== by 0x100012E98: main (in ./ex31)
==97331== Address 0x102dde080 is 1,776 bytes inside a block of size 1,780 alloc'd
==97331== at 0x100025EA1: malloc (vg_replace_malloc.c:303)
==97331== by 0x10010E8C1: PetscMallocAlign (mal.c:34)
==97331== by 0x10011063D: PetscTrMallocDefault (mtr.c:188)
==97331== by 0x1013EFDA0: TSResilCreate (tsresil.c:525)
==97331== by 0x10139A877: TSGetResil (ts.c:5252)
==97331== by 0x10138D17E: TSSetFromOptions (ts.c:421)
==97331== by 0x100011A47: SolveODE (in ./ex31)
==97331== by 0x100012E98: main (in ./ex31)
In tsresil.c:525(我在 PETSc 中的实现):
ierr = PetscHeaderCreate(resil,TSRESIL_CLASSID,"TSResil","Time stepping resilience","TS",comm,TSResilDestroy,TSResilView);CHKERRQ(ierr);
在inherit.c中:
22: /*
23: PetscHeaderCreate_Private - Creates a base PETSc object header and fills
24: in the default values. Called by the macro PetscHeaderCreate().
25: */
26: PetscErrorCode PetscHeaderCreate_Private(PetscObject h,PetscClassId classid,const char class_name[],const char descr[],const char mansec[],
27: MPI_Comm comm,PetscObjectDestroyFunction destroy,PetscObjectViewFunction view)
28: {
29: static PetscInt idcnt = 1;
30: PetscErrorCode ierr;
31: #if defined(PETSC_USE_LOG)
32: PetscObject *newPetscObjects;
33: PetscInt newPetscObjectsMaxCounts,i;
34: #endif
37: h->classid = classid;
38: h->type = 0;
39: h->class_name = (char*)class_name;
40: h->description = (char*)descr;
41: h->mansec = (char*)mansec;
...
PetscObject 是指向以下内容的指针:
typedef struct _p_PetscObject {
...
char *class_name; /* for example, "Vec" */
char *description;
...
因此,问题似乎与char* descr
的赋值有关,但我不明白为什么。大小 8 会通知指针错误,不是吗?
看起来 Valgrind 正在抱怨,因为您只为 PetscObject 分配了 1780 字节,而这 8 字节的写入(从字节 1776 开始)足以写入您没有分配的内存。
您需要增加分配的大小,或增加结构的大小,具体取决于分配的完整定义和方法。