c - 使用 scanf 和初始化定义 malloc 数组大小



>我正在尝试创建一个程序,要求用户提供数组的大小,然后要求用户填充它。

每当我启动程序时,"元素 %d"printf 都会将 %d 显示为一个大数字而不是 1。

如果我在将值输入数组后继续程序,调试器将崩溃。这是怎么回事?我是否不小心将地址放在阵列位置?谢谢

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int elements = 0;
printf("How many Elements will you enter?");
scanf("%d", &elements);
int* elementArray = malloc(sizeof(int) * elements);
int i = 0;
while (elementArray[i] != '')
{
printf("Element %d: ", elementArray[i]);
scanf("%d", &elementArray[i]);
i++;
}
free(elementArray);
return 0;
}

编辑:阅读评论,我的意思是printf("Element %d: ", elementArray[i]);应该在第一个循环中打印一个。虽然我应该将代码编辑为 elementArray[i] + 1,这样它就不会打印"元素 0"而不是元素 1。抱歉准系统代码,它已经完成了一半,我想在完成之前解决这个问题。将致力于现在给出的解决方案。感谢您的帮助

编辑2:感谢大家,尤其是Sharuya!这是我完成的代码。

void printArray(int* elemArray, int elements)
{
printf("The Array contains: ");
for (int k = 0; k < elements; k++)
{
printf("%d,t", elemArray[k]);
}
}
int main(void)
{
int elements = 0;
printf("How many Elements will you enter?");
scanf("%d", &elements);
int* elementArray = (int *)malloc(sizeof(int) * elements);
int input = 0;
for (int j = 0; j < elements; j++)
{
printf("Element %d: ", j + 1);
scanf("%dn", &input);
*(elementArray + j) = input;
}
printArray(elementArray, elements);
free(elementArray);
return 0;
}

现在唯一的问题是,在"元素 1:"和"元素 2:"打印f之间,我得到一个空行,它允许我输入一个数字,提交后,它照常继续。如果我提交一个包含 5 个元素的数组,它会要求我输入 6 个元素,但只出现了 5 个......这是怎么回事?

while (elementArray[i] != '')

此检查是问题所在

  1. malloc不保证初始化的内存将被zero filled。因此,您的循环可能会越过分配的内存并尝试读取程序不应该读取的内存(从而导致崩溃)
  2. 如果填充为零,您的代码将永远不会进入循环

你需要的是

while (i < elements)

此外,printf应该在scanf之后获得任何有意义的结果。如果您只想获取即将输入的索引,请使用printf("Element: %d", i)而不是elementArray[i]

有几个问题,让你问:

  1. 如果用户输入负值怎么办?
  2. 如果用户输入 0 怎么办?
  3. 如果用户输入的值非常大怎么办?
  4. 阵列分配是否成功?
  5. 分配后,我的阵列中有什么?
  6. 如果我的数组大小为 0,elemenArray[0] 是否有效?
  7. 我应该使用 for 循环,就像其他人在我的数组中遍历一样吗?

只要问自己这些问题就可以立即修复这个程序,并会让你完成下一个要写的一半。

您遇到的问题比打印索引以外的内容还要多。

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int elements = 0;
printf("How many Elements will you enter? ");
if((1!=scanf("%d", &elements))||(elements<1) ) // check return value, always a good idea
{   printf("Reading number failed.n");
return 1;
}
int* elementArray = malloc(sizeof(int) * elements);
int i = 0;
while ( (i<elements) // use the number you asked for to avoid writing beyond array
&& ((0==i) || (0 != elementArray[i-1]))) // stop when previously entered value is 0
{
printf("Element %d: ", i+1); // print the index
// instead of the non-initialised value
if(1!= scanf("%d", &elementArray[i]))
{
printf("Reading value failed!n");
free(elementArray); // cleanup
return 1;
}
i++;
}
if (i<elements)
{
printf("Stopped early because 0 was entered.n");
}
free(elementArray);   
return 0;
}

首先,您需要知道 malloc() 函数根据计算的大小动态分配内存(在 sizeof() 的帮助下)并返回此内存位置的地址。
但是,此地址不与任何数据类型相关联,即只有 void* 指针才能存储不完整数据类型的此地址。 因此,而不是提及

int* elementArray = malloc(sizeof(int) * elements);

提及并使用类型转换

int* elementArray = (int *)malloc(sizeof(int) * elements);

根据您的代码,elementArray 是一个指针,它将存储整数的地址

int *elementArray;
printf("Element %d: ", elementArray[i]);

因此,上面的行实际上将打印指针而不是索引指向的地址,因为递增指针与 elementArray 存储基址。

i.e elementArray++ is equal to elementArray+1 == elementArray[1] will point 
to the next memory location after 4 bytes.(since integer is stored in 4 bytes)

我已经修改了您的代码以纠正您的错误

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int elements = 0;
printf("How many Elements will you enter?");
scanf("%d", &elements);
//the below statement actually allocates contiguous block of memory equal 
//to no of elements and the pointer points only to first element.
//Incrementing it will point to next element
int* elementArray =(int *) malloc(sizeof(int) * elements);  
//typecasting of void* pointer to int*
int i = 0,elm;
for(i=0;i<elements;i++)                                           
//Since u know iterations will be equal to no of elements it is better to use for loop
{
printf("Element %d: ", i);
scanf("%d", &elm);
*(elementArray+i)=elm;
//Storing the data in elm and making the pointer point to next free 
//dynamically allocated block of memory and using * operator the value at 
//this location is accessed and storing elm value in it
}
for(i=0;i<elements;i++)
printf("%d",*(elementArray+i));
free(elementArray);
return 0;
}

这段代码有效,我希望它能!!事情变得清晰起来

最新更新