我是C的新手,还在学习指针。当我在使用printf时遇到Access Violation Read Loaction错误时,我只是通过尝试模拟追加到数组来测试我对指针的理解。这是代码:
#include <stdio.h>
#include <stdlib.h>
int arraySize(int *arrayToSize);
void changeAll(int ***a1PtrPtrPtr, int nToAdd){
int *bPtr = (int *)malloc((arraySize(**a1PtrPtrPtr) + 1) * sizeof(int));
int i = 0;
while (*(**a1PtrPtrPtr + i) != -1){
bPtr[i] = *(**a1PtrPtrPtr + i);
i++;
}
bPtr[i] = nToAdd; i++;
bPtr[i] = -1;
*a1PtrPtrPtr = &bPtr;
}
int main(void){
int a[4] = { 1, 2, 3, -1 };
int *aPtr = a;
int **aPtrPtr = &aPtr;
int ***aPtrPtrPtr = &aPtrPtr;
int n = 4;
changeAll(aPtrPtrPtr, n);
int counter = 0;
while (counter < 5){
int temp = *(*aPtrPtr + counter);
printf("%d is %d", counter, temp );
counter++;
}
return 0;
}
int arraySize(int *arrayToSize){
int sizeTemp = 0;
int i = 0;
while (arrayToSize[i] != -1){
sizeTemp++;
i++;
}
sizeTemp++;
return sizeTemp;
}
当counter = 1时,我第二次在main()中的while循环中打印错误。我不明白的是,如果我注释掉printf语句并查看我的temp值的值IDE(MVSE 2013)它完全符合我的要求和预期,即temp将为1然后2,3,4,-1。
请发生什么事,并提前感谢您的帮助。
答案 0 :(得分:1)
首先,如果你想知道这个如何出现有时会起作用,你真的应该read this stellar answer到另一个有点相关的问题。
简而言之,您正在从函数内部将地址保存到自动变量,然后在函数返回后处理所述地址仍然有效。自动变量是指向动态数据的指针是无关紧要的。一旦函数到期,变量本身就不再有效,因此取消引用它的use-to-address会调用未定义的行为:
void changeAll(int ***a1PtrPtrPtr, int nToAdd)
{
// NOTE: local variable here
int *bPtr = (int *)malloc((arraySize(**a1PtrPtrPtr) + 1) * sizeof(int));
int i = 0;
while (*(**a1PtrPtrPtr + i) != -1){
bPtr[i] = *(**a1PtrPtrPtr + i);
i++;
}
bPtr[i] = nToAdd; i++;
bPtr[i] = -1;
// NOTE: saving address of local variable here
*a1PtrPtrPtr = &bPtr;
}
如何设置,最快的解决方法就是:
**a1PtrPtrPtr = bPtr;
而不是你拥有的。这会将动态分配结果保存到正确的位置(最终将aPtr
中的地址保存在main()
中)。它看起来很可怕(坦率地说,它是),但它会起作用。
祝你好运。