C ";至于;循环更改函数内的指针值
中项目的链接 因此,我对主函数中的案例5有一个问题。其中调用了load_array()。实际函数位于第120行的functions.c中C ";至于;循环更改函数内的指针值,c,loops,for-loop,C,Loops,For Loop,中项目的链接 因此,我对主函数中的案例5有一个问题。其中调用了load_array()。实际函数位于第120行的functions.c中 问题是for循环将int*size的值从5更改为23,现在我们有足够的代码继续。首先,load\u array用于分配和填充数组,通过两个指针将其位置和大小传回,一个用作inout(size),另一个仅用作输出(p)init用于进行分配,有一个调用端保存变量,一个int-elements和(大概)int*arr=NULL 问题是,在传递过程中,它们不是作为同一
问题是for循环将int*size的值从5更改为23,现在我们有足够的代码继续。首先,
load\u array
用于分配和填充数组,通过两个指针将其位置和大小传回,一个用作inout(size),另一个仅用作输出(p)init
用于进行分配,有一个调用端保存变量,一个int-elements
和(大概)int*arr=NULL
问题是,在传递过程中,它们不是作为同一类型传递的。调用load\u array
的地址是arr
,因此是int**
,但是声明说它只是int*
。它被传递到init
,它需要一个int**
,它很可能在那里工作,因为它实际上是一个(但它仍然是一种无效的指针类型转换方法),但是当load\u数组开始填充内容时,它正在写入p+i
p
在该点指向arr
,它不是int,因此即使i
较低,这也是放置数据的错误位置。这首先导致指向的缓冲区arr
丢失,其次是arr
中的无效数据,这样以后访问它将导致未定义的行为,第三是(一旦i
大于sizeof(int*)/sizeof(int)
)覆盖不相关的内存,例如元素的内容
,这可能是一个相邻变量
一种可能的内存布局可能是元素
位于堆栈上,比如说FP+12..15,然后有四个未使用的字节保持arr
在FP+8..11对齐,arr
位于FP+0..7。这将解释为什么步骤i=3
特别会导致元素
(别名*大小
)发生变化
您应该做的是修复p
的类型,并在load\u array
中使用*p
,就像在init
中使用一样 编译器应该对您大喊大叫,因为您传递给load\u array
的最后一个参数与函数形式参数不匹配,而它又与init
所期望的不匹配
如果load\u array
函数中的p
确实是指向指针的指针(即参数是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]);
...
}
您已经演示了如何调用load\u array
,这是一个好主意,但还不够,请演示如何声明file\u name
、元素和arr
。什么是init
?没有足够的信息。除了调用load\u array
的环境外,init
做什么?你是说int**p
,这样init
就可以分配给*p
?那么p
指向什么呢?它看起来像是一个典型的缓冲区溢出,p
可能指向堆栈上分配的一个自动变量,它不是至少包含sz
int的数组。因此,在void load_数组(char*fn,int*size,int*p)
中,p
是int*
,然后调用init(p,sz)
,其原型为void init(int**p,int size)
。你是在告诉我们你的编译器对此没什么可说的吗?请不要链接,所有内容都应该包含在问题中。你读到了吗。