初始化成功后,结构成员被垃圾值覆盖
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_hv
和 p[1].overlap_vh
:
p[i].child[index] = j;
index++;
【讨论】:
以上是关于初始化成功后,结构成员被垃圾值覆盖的主要内容,如果未能解决你的问题,请参考以下文章
工具,Visual Studio 设置来检查未初始化的类成员