所以我在main函数中遇到了case 5的问题。调用load_array()的位置。实际功能位于第120行的functions.c
中问题是for循环将int * size的值从5改为23
答案 0 :(得分:3)
编译器应该对你大喊大叫,因为你传递给load_array
的最后一个参数与函数形式参数不匹配,而它反过来与init
不匹配预计。
如果p
函数中的load_array
确实是指向指针的指针(即参数为int **p
),那么scanf
调用错误就像表达式一样(p + i)
也是指向指针的指针。这很可能是导致问题的原因,因为它会导致未定义的行为并将输入写入除您期望的其他地方。
要解决此问题,首先需要修复参数类型,然后在使用p
时使用解除引用运算符,如*p + i
中所示。
简而言之,为了正确,代码应该看起来像
// Note extra asterisk here
// |
// v
void load_array(char* fn, int* size, int** p)
{
...
// Note extra asterisk here
// |
// v
fscanf(fp, "%d", *p + i);
// Or fscanf(fp, "%d", &(*p)[i]);
...
}
答案 1 :(得分:1)
现在我们有足够的代码继续下去。首先,load_array
用于分配和填充数组,通过两个指针传递其位置和大小,一个用作inout(大小),另一个用作输出(p)。 init
用于进行分配,并且有一个包含变量的调用方,int elements
和(大概)int *arr=NULL
。
问题是,这些并没有沿着同一类型传递。对load_array
的调用取arr
的地址,因此为int**
,但声明称其仅为int*
。它传递给期望init
的{{1}},并且它可能在那里工作,因为它实际上是一个(但它仍然是转换指针类型的无效方式),但是当int**
开始填写内容正在写入load_array
。
p+i
指向p
,这不是一个int,所以即使arr
为低,这也是放置数据的错误位置。这首先导致丢失缓冲区i
,其次是arr
中的无效数据,以便稍后访问它将导致未定义的行为,第三次(arr
一次变得大于{{1}覆盖不相关的内存,例如可能是邻近变量的i
的内容。
可能的内存布局可能是sizeof(int*)/sizeof(int)
位于堆栈上,让我们说FP + 12..15,然后有四个未使用的字节让elements
在FP +处对齐8..11,elements
位于FP + 0..7。这可以解释为什么步骤arr
会导致arr
(别名i=3
)发生变化。
您应该做的是修复elements
的类型并在*size
中使用p
,就像在*p
中使用的那样。