【问题标题】:Pointer value changing unexpectedly when passed to function传递给函数时指针值意外更改
【发布时间】:2019-11-01 01:35:38
【问题描述】:

所以我试图在 C 中实现一个 arrayList,但我遇到了一些错误。当主函数的for循环中i为4时,调用insertArrayList插入数字4。将4插入我的内容数组后,我的数组的前5个元素分别为0,1,2,3,4。但是在我调用 PrintArray 之后,我数组中的第一个元素更改为 6422016。我不知道为什么会这样。任何帮助,将不胜感激。谢谢。

#include <stdlib.h>
#include <math.h>

struct ArrayList{
    int numItemsInserted;
    int size;
    int *contents;
};

void initializeArrayList(struct ArrayList *a, int size){
    (*a).numItemsInserted= floor(size / 2);
    (*a).size = size;
    (*a).contents = malloc(sizeof(int) * size);
}

void PrintArray(struct ArrayList *a){
    for (int i = 0 ; i < (*a).numItemsInserted; i++){
        printf("%i ", (*a).contents[i]);
    }
    printf("\n");
}
struct ArrayList insertArrayList(struct ArrayList *a, int num){
    if((*a).numItemsInserted == (*a).size){
        int newContents[(*a).size * 2];
        for (int i = 0; i < (*a).size; i++){
            newContents[i] = (*a).contents[i];
        }


        (*a).contents = newContents;
        (*a).size *= 2;

    }
    (*a).contents[(*a).numItemsInserted] = num;
    (*a).numItemsInserted += 1;
    PrintArray(a);
}


int main() {
    struct ArrayList a1;
    initializeArrayList(&a1, 1);
    for (int i =0; i < 10; i ++){
        if (i == 1){
            printf("a");

        }
        insertArrayList(&a1, i);
    }

    return 0;
}```

【问题讨论】:

  • 第一,原型; struct ArrayList insertArrayList(struct ArrayList *a, int num) 应该写成返回一个指向结构体的指针:struct ArrayList * insertArrayList(... 其次,因为它不是 void 函数,它需要在底部有一个 return 语句来返回你最终决定使用的任何类型。

标签: c pointers


【解决方案1】:

(*a).contents = newContents; 将本地数组newContents 的(第一个元素)地址分配给(*a).contents。一旦ArrayList 返回,newContents 就不再存在于 C 计算模型中。

增加数组的正确方法是使用realloc 请求更大的分配。首先,请求更多内存:

int *NewContents = realloc(a->contents, NumberOfElementsDesired * sizeof *NewContents);

然后,测试请求是成功还是失败:

if (NewContents == NULL)
{
    fprintf(stderr, "Error, failed to allocate memory.\n");
    exit(EXIT_FAILURE);
}

然后,记录新内存的地址:

a->contents = NewContents;

然后,填写新项目。

【讨论】:

  • 我的方法不应该还有效吗?我不再需要 newContents 了。我只是做了它,以便我可以为其分配内容。我仍然不明白这与我的指针更改值的值有什么关系。
  • @Jonathan:当newContents 在带有int newContents[(*a).size * 2]; 的函数内定义时,会创建一个临时 数组。它使用在函数执行期间自动分配的内存(通常在硬件堆栈上),并在函数结束时自动释放。函数结束后,该内存可能会被重新用于其他目的。语句(*a).contents = newContents;永久newContents的地址记录在(*a).contents中。这意味着,当您稍后尝试使用 (*a).contents 时,您正在使用已被其他东西更改的内存。
  • @Jonathan:另外,你的问题并没有说指针改变了值。它说数组的第一个元素改变了值。这是因为(*a).contents 指向的内存不再保留用于数组newContents。您的程序中的某些东西正在将该内存用于其他目的,这会改变那里的值。
  • 好的,我想我可能明白你想说什么了。让我试着重申一下。由于 newContents 数组是临时的,一旦数组被销毁,现在允许为该数组分配的内存由程序操作吗?
  • @Jonathan:是的,程序可能会将内存重新用于其他目的。
猜你喜欢
  • 2021-03-03
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多