C语言 在动态数组中存储值



我想从键盘(或从文件:./a)中获取数字。& lt;文件)并将它们存储在数组中。其思想是数组的长度是未知的。

#include <stdio.h>
#include <stdlib.h>
int* newElem(){
int* elm= malloc(sizeof(int));
  if (elm == NULL) {
    printf("nError: memory allocation failed.n");
    exit(-1);
  }
return elm;
}

int main(){
int *array,x,size,i=0;
    while( scanf("%d",&x)==1 ){
        array= newElem();
        array[i]=x;
        i++;
    }
size=i;
free(array);
printf("size=%d",size);

return(0);
}

为什么当我输入:1 2 3 4 5 6 7 8

在你的代码中

array= newElem();

每次都会覆盖现有的指针(内存)。因此,array[i]无效,这本质上是越界访问,这反过来又调用了未定义的行为。您需要使用realloc()来重新调整分配的内存大小。

简单。

array= newElem();
array[i]=x;
i++;

newElem()总是返回int[1],而您试图访问[n]

首先,您需要知道数组是由连续的地址组成的序列。这意味着如果第一个元素的地址是0,那么第二个元素的地址将是1,然后是2,依此类推…

当你在C中说x[10]时,你实际上是在说*(x + 10),这意味着"从第一个元素(0)开始,向前移动10个地址(+ 10),并将该地址的内容(*运算符)作为int。

所以你看,元素之间有一个数学关系,它们在内存中都是紧挨着的。

现在,到你的代码…

当你调用array= newElem();时,你的指针array指向新分配的地址。但是,在之前指向的任何先前的地址array都是丢失的,这会导致您的意外行为和内存泄漏。

当你第一次调用array= newElem()时,假设在地址A处分配了一个整数,下一次在地址B处分配了一个新的整数,以此类推…

在第一次迭代时,使用i = 0:

while( scanf("%d",&x)==1 ){
    array= newElem();
    // array points to A
    array[i]=x;
    // array[0] = x
    // or *(array + 0) = x
    // same as *(array) = x
    i++;
    // i = 1
}

现在你很可能会有一个错误(i = 1):

while( scanf("%d",&x)==1 ){
    array= newElem();
    // address A is lost, and now array points to B
    array[i]=x;
    // array[1] = x; -> likely an ERROR
    // *(array + 1) = x
    i++;
    // i = 2
}

在第二次迭代中,你试图访问array指向的新地址旁边的地址,这将是C,这就是为什么你得到了一个违规。

您的代码不维护数组元素之间的关系,您实际上是在每次迭代中创建单个整数,然后尝试访问内存地址,但实际上是访问无效的内存地址。

一开始这不是一个非常简单的概念,如果你需要进一步澄清,请注释

相关内容

  • 没有找到相关文章

最新更新