使用scanf定义malloc数组大小并初始化

时间:2017-06-14 05:30:24

标签: c arrays pointers malloc scanf

我正在尝试创建一个程序,询问用户是否有数组大小,然后要求用户填充它。

每当我启动程序时,“Element%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] != '\0')
    {
        printf("Element %d: ", elementArray[i]);
        scanf("%d", &elementArray[i]);
        i++;
    }
    free(elementArray);

    return 0;
}

编辑:阅读评论,我的意思是printf("Element %d: ", elementArray[i]);应该在第一个循环中打印一个。虽然我应该将代码编辑为elementArray [i] + 1,因此它不会打印“元素0”而不是元素1.对于准系统代码的道歉,它完成了一半,我想在完成它之前解决这个问题。将解决现在提供的解决方案。谢谢你的帮助

EDIT2:感谢大家,特别是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("%d\n", &input);
        *(elementArray + j) = input;
    }

    printArray(elementArray, elements);

    free(elementArray);

    return 0;
}

现在唯一的问题是,在“元素1:”和“元素2:”printf之间,我得到一个空行,允许我输入一个数字,在提交时,它继续正常。如果我提交一个包含5个元素的数组,它会询问我6个元素,只有5个元素出现......这里发生了什么?

4 个答案:

答案 0 :(得分:2)

while (elementArray[i] != '\0')

此检查是问题

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

    while (i < elements)
    

    同样printf应该在scanf之后获得任何有意义的结果。如果您只想获取要输入的索引,请使用printf("Element: %d", i)代替elementArray[i]

答案 1 :(得分:1)

有几个问题,请问:

  1. 如果用户输入负值怎么办?
  2. 如果用户输入0怎么办?
  3. 如果用户输入一个非常大的值会怎样?
  4. 阵列分配成功了吗?
  5. 分配后我的数组中有什么?
  6. 如果我的数组大小为0,elemenArray [0]是否有效?
  7. 我是否应该使用for循环,就像每个人都可以通过我的阵列一样?
  8. 只要问问自己这些问题会立即解决这个问题,并且会让你完成下一个问题的一半。

答案 2 :(得分:0)

除了索引以外的其他内容之外,还有其他问题。

#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;
}

答案 3 :(得分: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;
}

此代码有效,我希望它能让事情变得清晰!