Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C ";至于;循环更改函数内的指针值_C_Loops_For Loop - Fatal编程技术网

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 问题是,在传递过程中,它们不是作为同一

中项目的链接

因此,我对主函数中的案例5有一个问题。其中调用了load_array()。实际函数位于第120行的functions.c中


问题是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)
。你是在告诉我们你的编译器对此没什么可说的吗?请不要链接,所有内容都应该包含在问题中。你读到了吗。