初始化成功后,结构成员被垃圾值覆盖

Posted

技术标签:

【中文标题】初始化成功后,结构成员被垃圾值覆盖【英文标题】:struct member gets overwritten by garbage value after successful initialization 【发布时间】:2017-12-02 23:43:28 【问题描述】:

我已经调试这个函数很长一段时间了,我无法理解这段代码会发生什么。

    void make_points(DocSpec instance, Tree *myTree, Point *p)
int i, j, k, index = 0;

for(i = 0; i < instance.numPt; i++)
    
        p[i].x = instance.xCoordinates[i];
        p[i].y = instance.yCoordinates[i];
        p[i].parent = myTree[i].parent;
        p[i].num_children = 0;
        for(k = 0; k < MAX_NUM_CHILDREN; k++)
            
                p[i].child[k] = 0;
            
        for(j = 0; j < instance.numPt; j++)
            
                if((i != j) && (myTree[j].parent == i))
                    
                        p[i].num_children++;
                        p[i].child[index] = j;
                        index++;
                    
            
         p[i].overlap_hv = -1;
         p[i].overlap_vh = -1;
         index = 0;
     

printf("p[1].index = %d;\n", p[1].index);
printf("p[1].x = %d;\n", p[1].x);
printf("p[1].y = %d;\n", p[1].y);
printf("p[1].parent = %d;\n", p[1].parent);
printf("p[1].num_children = %d;\n", p[1].num_children);

printf("p[1].child[8] = ");
index = 0;
for(i = 0; i < MAX_NUM_CHILDREN; i++)
    
        if(p[1].child[i] != 0 && index == 0)
            
                printf("%d", p[1].child[i]);
            
        elseif(p[1].child[i] != 0)
            printf(", %d", p[1].child[i]);
    
print(";\n");
printf("p[1].overlap_hv = %d;\n", p[1].overlap_hv);
printf("p[1].overlap_vh = %d;\n", p[1].overlap_vh);

运行该函数后得到的输出如下:

p[1].index = 1;
p[1].x = 0;
p[1].y = 90;
p[1].parent = 5;
p[1].num_children = 0;
p[1].child[8] = 1563515760, 1768448814, 945513580, 540876893;
p[1].overlap_hv = 909455739;
p[1].overlap_vh = 892679225;

但应该是:

p[1].index = 1;
p[1].x = 0;
p[1].y = 90;
p[1].parent = 5;
p[1].num_children = 0;
p[1].child[8] = ;
p[1].overlap_hv = -1;
p[1].overlap_vh = -1;

当我在我的程序上运行 gdb 时,我注意到 p[1] 的值已正确初始化,但是当

printf("p[1].x = %d;\n", p[1].x);

被执行 - p[1].child[4], p[1].child[5], p[1].child[6], p[1].child[7], p[1] .overlap_hv、p[1].overlap_vh 都会被垃圾值覆盖。

我不知道 printf 语句为什么或如何改变我的结构成员的值。

任何帮助将不胜感激。

【问题讨论】:

为什么要使用 C 和 C++ 标签?选择一个。 一个疯狂的猜测是代码在某处写入越界。 Point看起来像什么,积分及其孩子的空间是如何分配的? 由于代码不完整,很难重现错误。我可以猜到 p 不是指向数组第一个元素的指针,而是指向单个 Point 并且 p[1] 不存在并指向一些随机垃圾内存。但这只是一个猜测,因为我看不到代码。 请提供Minimal, Complete, and Verifiable example 这里有一个调试建议:放一个 printf("Ctor %p\n", this);在每个 Point 类的构造函数中,以及 printf("Dtor %p\n", this);在你的 Point 类的析构函数中。然后放一个 printf("p is at %p\n", &p[1]);在问题发生的地方。然后运行程序,并检查输出以查看在您的症状出现时 p 是否是有效的 Point 对象。我敢打赌,它要么在那个位置永远无效,要么早早被摧毁;无论哪种方式,您都在取消引用无效指针,这就是该位置的内存意外更改的原因。 【参考方案1】:

原来我在重新分配内存时没有使用正确的类型转换。与 Valgrind 的快速检查让我找到了罪魁祸首。

曾经

p = (Point*) realloc(p, instance.numPt * sizeof(p));

这解决了它

p = (Point*) realloc(p, instance.numPt * sizeof(Point));

感谢大家的建议。

【讨论】:

【参考方案2】:

我的猜测是index 正在跨越子边界,j 会覆盖下一个结构成员 p[1].overlap_hvp[1].overlap_vh

                    p[i].child[index] = j;
                    index++;

【讨论】:

以上是关于初始化成功后,结构成员被垃圾值覆盖的主要内容,如果未能解决你的问题,请参考以下文章

覆盖基类成员变量的初始值

类成员初始化的首选方式?

工具,Visual Studio 设置来检查未初始化的类成员

2.6 自定义数据结构

CUDA:struct的共享数据成员和该struct的引用成员具有不同的地址,值

宏定义中对结构体变量进行初始化,结构体成员变量前为啥加点号??