我想从键盘(或从文件:./ a.out<文件)获取数字并将它们存储在数组中。这个想法是数组的长度是未知的。
#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
答案 0 :(得分:0)
在您的代码中
array= newElem();
每次都会覆盖现有的指针(内存)。所以,array[i]
变得无效,这实际上是一个超出范围的访问,而这些访问又会调用undefined behavior。您需要使用realloc()
来重新调整已分配的内存大小。
答案 1 :(得分:0)
简单。
array= newElem();
array[i]=x;
i++;
newElem()总是返回int [1]而你试图访问[n]
答案 2 :(得分:0)
首先,您需要知道数组是连续地址的序列。 这意味着如果第一个元素的地址是0,则第二个元素的地址将是1,而下一个元素的地址将是...,等等...
当你在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
指向的地址 NEXT TO ,这将是C,这就是您违规的原因。
您的代码不维护数组元素之间的关系,您实际上是在每次迭代中创建单个整数,然后尝试 然后访问,但实际上是在访问无效的内存地址。
首先,这不是一个非常简单的概念,如果您需要进一步澄清,请发表评论。