问题:
我很确定我这里的问题是对指针发生的事情的典型误解。我将在下面发布内存中发生的事情,因为我在这里的主要目标是学习如何正确调试,所以这可能是一篇关于其他微不足道的问题的长篇文章。
首先是代码:
/*Generate array with 500 to 1000 elements*/
/*In the calling function, I create something like 'int* x;' and pass '&x'*/
void gen_array(int** arr){
int size = rand() % (1001 - 500) + 500;
int i;
*arr = (int*) malloc(size*sizeof(int));
if (*arr == NULL){
printf("Allocation failed\n");
exit(1); //I know this is probably bad form
}
//Fill with some random numbers from 1 to 1000
for (i = 0; i < size; ++i)
*arr[i] = rand() % 1001;
}
它在 for
循环的第一次迭代后中断(即当 i==1
时)。我不确定我是在使用 malloc
分配错误,还是在循环中分配错误。
这样调用:
int* x = NULL; //Tried without '= NULL' as well
gen_array(&x);
具体错误:
Unhandled exception at 0x00265E55 in test.exe: 0xC0000005: Access violation writing location 0xCCCCCCCC.
这是在 first-chance exception 之后在完全相同的位置,但它们是在同一行代码中生成的(并且在执行期间的相同迭代中)。
我的分析尝试:
如果有帮助,这里是一次尝试调试的(相关)分步(我在 Visual Studio 中编译)。我想知道如何使用此信息来帮助我将来进行调试。
- 在调用函数的开头,
x = 0xcccccccc
(0xcccccccc=-842150451
似乎是编译器用来填充未初始化值的内容)。设置为NULL
后,当然等于0x00000000
。 - 调用
gen_array(int** arr)
,因为我将指针传递给指针,所以本地“双指针”是指向 NULL 指针的地址:arr= 0x0018facc {0x00000000 {???}}
。 (这显示了所指向内容的值,因为 NULL 指针没有指向任何内容,所以有???
) - 调用
malloc
:现在arr=0x0018facc {0x00e97048 {-842150451}}
,所以*arr
指向一个未初始化的值 - 第一次迭代(
i==0
),生成的数字是588
,所以现在arr=0x0018facc {0x00e97048 {588}}
(即*arr
指向的值是588
)
i
增加到 1
后下一次迭代崩溃。由于这是访问冲突,我通常会猜测 arr+1
不希望被写入。但违规位置位于 0xCCCCCCCC
,此编译器用于未初始化数据的值。这是因为 arr+1
在技术上未初始化吗?
编辑:按照@GrzegorzSzpetkowski 的建议,我尝试将*arr[i]
更改为(*arr)[i]
。它停止破裂了!但是,没有新的随机值被创建/放置到数组中(这就是为什么我担心根本没有创建数组)。
编辑 2: 根据 @EOF 的建议,我更改了函数以返回大小,这样我就可以使用类似 int length = gen_array(&x);
我知道我也可以尝试从函数返回一个 int*
,但我想知道在从要初始化的调用函数传递指针的情况下具体发生了什么.
最佳答案
请检查 * 和 [] 的运算符优先级 http://en.cppreference.com/w/c/language/operator_precedence
*arr[i] = rand() % 1001;
表示
*(arr[i]) = rand() % 1001;
但你想要
(*arr)[i] = rand() % 1001;
关于c - 将指针传递给在 C 中创建(随机大小)填充随机整数的数组的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37308419/