gpt4 book ai didi

c - 取消引用指针会破坏它的值(value)?

转载 作者:太空宇宙 更新时间:2023-11-04 02:11:46 24 4
gpt4 key购买 nike

我有一个方法应该在数组的末尾添加一个“节点”。当我找到一个地方来存储值(有效)时,这奇怪地从旧地址中删除了值。

void appendAtEndOfArray(struct node * item,struct node * arrayPointer){
int i=0;
while (arrayPointer[i].name!='\0') {
i++;
}
arrayPointer[i]=*item; // after this the original memory at &item is changed to '\0'
}

这可能很简单,但我是 C 和整个指针的新手....

我这样调用方法:

void addVertice(char source, char destination,int cost){
struct node * sourceNode = addNode(source);
struct node * destinationNode = addNode(destination);
appendAtEndOfArray(destinationNode,sourceNode->children);
appendAtEndOfArray(sourceNode,destinationNode->parents);
}

我的节点是这样定义的:

struct node            {
char name;
bool visited;
int distance;
struct node *children[30];
struct node *parents[30];
} nodes[30];

struct node * addNode(char name){
int n=getNodeByName(name); // if exists reuse
if (n==-1) {
n=++lastNodeIndex;
}
nodes[n].name = name;
nodes[n].visited=false;
return &nodes[n];
}

有人可以指出我做错了什么吗?

最佳答案

您看到此行为是因为 appendAtEndOfArray 的定义与您传递给它的参数之间存在类型不匹配。 NuclearGhost 在评论中指出了这一点。正如他所说,函数声明需要更改为

void appendAtEndOfArray(struct node * item, struct node * arrayPointer[])

您在更改数组参数后看到的“错误访问”错误来自 while 循环。更正函数声明后,arrayPointer[i] 的类型为 struct node *。由于您现在通过指针访问结构成员,因此必须将 .(点)运算符更改为 ->:

while (arrayPointer[i]->name != '\0') {

现在你可以采纳 twalberg 的建议直接给 item 赋值:

arrayPointer[i] = item;

还有一个问题需要更正:arrayPointer[i]是指针类型,所以可以有空值。在取消引用指针之前需要检查该条件,否则程序可能会因段错误而崩溃:

while (arrayPointer[i] && (arrayPointer[i]->name != '\0')) {

编辑:对您担心代码“奇怪地从旧地址中删除了值”背后的“原因”的额外解释。

在您的原始代码中,当您将 sourceNode->children 传递给 appendAtEndOfArray 时,编译器会因类型不匹配而发出警告,但仍会生成代码。它可以这样做是因为你传入的值和函数期望的值都是内存地址——指针的“类型”简单地决定了编译器如何处理指针所指的内存,所以不需要实际的数据转换执行。

在我的机器上,一个 32 位 x86 平台,指针是 4 个字节,你的 struct node 类型是 252 个字节(由于填充 char 和 bool 类型最多 4 个字节,每个).当 appendAtEndOfArrayitem 分配给 arrayPointer 的第一个元素时,如(来自原始代码):

arrayPointer[i]=*item;

系统将 252 字节的数据从结构复制到一个内存位置,该位置旨在保存一个 4 字节的指针。结果,arrayPointer[i] 之后的 248 个字节被覆盖。由于节点是在一个数组中分配的,这意味着 nodes 数组中的下一个节点的一部分将被覆盖。

例如,考虑调用

appendAtEndOfArray(destinationNode,sourceNode->children);

假设 sourceNode->children 数组为空,那么 destinationNode 将被分配给第 0 个元素。由于赋值实际上是将整个结构内容写入第 0 个元素的内存位置,这将覆盖 sourceNode->children 的所有 30 个元素(120 字节)以及所有 sourceNode ->parents(另外 120 个字节),留下另外 12 个字节的数据溢出到节点数组中的下一个元素,它(在我的机器上)覆盖了 name拜访成员。

关于c - 取消引用指针会破坏它的值(value)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13145326/

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