【问题标题】:C Pointers and Access Violation Read LocationC 指针和访问冲突读取位置
【发布时间】:2015-03-23 04:10:44
【问题描述】:

我是 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。

请问这是怎么回事,提前感谢您的帮助。

【问题讨论】:

  • *a1PtrPtrPtr = &amp;bPtr - 你知道bPtr 在该函数返回后甚至不存在,对吧?您正在保存函数返回后早已消失的自动变量的地址。
  • @WhozCraig 这对我来说看起来不错。
  • 我有点困惑,因为我认为内存是用 malloc 分配的,直到我释放它。不是这样吗?
  • @Mick 内存地址hold in bPtr,是的;地址 of bPtr itself 的内存,no.
  • 使用int temp = *(*aPtrPtr)++;。运行你的while循环while (counter &lt; 4)

标签: c pointers


【解决方案1】:

首先,如果您想知道这个看起来有时是如何工作的,您真的应该 read this stellar answer 回答另一个有点相关的问题。

简而言之,您将地址从函数内部保存到自动变量中,然后将所述地址视为在函数返回后仍然有效。自动变量是引用动态数据的指针是无关紧要的。一旦函数过期,变量本身就不再有效,因此取消引用它的使用地址会调用未定义的行为:

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() 中)。它看起来很可怕(坦率地说,确实如此),但它会起作用。

祝你好运。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 2020-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多