【发布时间】:2023-02-07 10:53:11
【问题描述】:
我试图通过将每个结构向左移动然后将我的数组重新分配一个较小的大小来从结构的动态数组中删除一个元素。
我的问题是:*(p[i])=*(p[i]+1); 和 (*p)[i]=(*p)[i+1]; 之间有什么区别,为什么第二个有效而第一个代码无效,从而导致分段错误。
void rm_event(struct events **p, int index, int qtty){
for(int i=index; i<qtty-1; i++){
*(p[i])=*(p[i]+1); // (*p)[i]=(*p)[i+1];
}
struct events *tmp;
tmp=(struct events*)realloc(*p, sizeof(struct events)*(qtty-1));
if(tmp!=NULL)
*p=tmp;
}
【问题讨论】:
-
*(p[i])取消引用p的地址,偏移量为i(这是p之外的内存),而(*p)[i]取消引用p,然后用i偏移它。填写一些随机数,假设地址 10 上的p指向地址 30,i为 5,*(p[i])将给出*(10+5)=*15,而(*p)[i]给出(*10)+5给出 @ 987654338@ =35:两个完全不同的地址。 -
表达式
*(p[i])与p[i][0]相同。如果p没有指向一个数组,那么你就会越界。*(p[i]+1)与p[i][1]相同。 -
struct events **p,可以以多种方式使用 - 在没有附加信息的情况下模棱两可。它可以是 1) 指向结构事件指针数组的第一个元素的指针,2) 指向结构事件数组的第一个元素的指针数组的第一个元素的指针,或 3) 指向指针的指针到结构事件数组的第一个元素。通常,在这种情况下,它是#3。在不同的情况下,不同的取消引用模式是正确的与未定义的行为。编译器无法分辨,您必须为您正在使用的语义获得正确的语法。 -
与其尝试逐一复制结构,不如查看
memmove()来替换复杂的for()正文……这项工作已经为您完成。
标签: c function for-loop dynamic