首页 文章

C编程创建动态数组

提问于
浏览
-3

到目前为止,您已创建了固定大小的静态数组 . 动态数组可以使用结构和malloc()来改变它们的大小 . 阵列已满:分配新的内存块 . 将数据从一个指针复制到另一个指针 . 释放旧指针 . 将新指针分配给动态数组结构

您只需实现函数来初始化动态数组并展开动态数组 . 按照注释查看您需要编码的内容 . 需要代码的注释有TODO:写在其中memcpy(void * dest,void * src,int bytes)一个用于在指针之间复制内存的有用函数 . 参数1:要复制到的目标指针 . 参数2:您要复制的源指针 . 参数3:要复制的字节数

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//The dynamic array struct.  This maintains my pointer to memory, effective size and maximum size
typedef struct
{
    double *arrayPointer;
    int effectiveSize;
    int maximumSize;
} DynamicArray;

//Initialize the dynamic array
void CreateArray(DynamicArray *mArray, int initialSize)
{
    //TODO: Use malloc to create an array of the initial size.  Assign to the arrayPointer variable

    //TODO: Set effective size to 0 and maximum size to the initial size
}

//Expand the array to a new size
void ExpandArray(DynamicArray *mArray, int newSize)
{
    //TODO: Create a new pointer (double *newArray) and set it with a malloc call of the new size

    //TODO: Using either memcpy or a for loop, copy all of the data from the old array to the new one.
    //You are only copying to mArray->maximumSize, not the new size.

    //TODO: Using the free function, release the previous mArray->arrayPointer

    //TODO: Update mArray with the new pointer and the new maximum size.  Effective size does not change.
}

//Add a new value from the user to the array
void AddValue(DynamicArray *mArray)
{
    //Get the input
    double input;
    printf("Enter a new value: ");
    scanf_s("%lf", &input);

    //Assign the input to the array.  Increase effective size
    mArray->arrayPointer[mArray->effectiveSize] = input;
    mArray->effectiveSize++;

    //If effective size is now the same as maximum size we need to expand.
    if (mArray->effectiveSize == mArray->maximumSize)
    {
        //Output that we are expanding
        printf("Expanding array from %d to %d\n", mArray->maximumSize, mArray->maximumSize * 2);

        //Double the size of the array
        ExpandArray(mArray, mArray->maximumSize * 2);
    }
}

//Print the array
void PrintArray(const DynamicArray *mArray)
{
    int i;

    //Walk through the array up to effective size and print the values
    for (i = 0; i < mArray->effectiveSize; i++)
    {
        printf("%.2lf ", mArray->arrayPointer[i]);
    }
    printf("\n");
}

int main(void)
{
    int i;

    //Create my dynamic array of size 5
    DynamicArray mArray;
    CreateArray(&mArray, 5);

    //Add five values to it
    for (i = 0; i < 5; i++)
    {
        AddValue(&mArray);
    }

    //Print the array
    PrintArray(&mArray);

    //Add five more values
    for (i = 0; i < 5; i++)
    {
        AddValue(&mArray);
    }

    //Print the array
    PrintArray(&mArray);
    system("pause");
}

图片是它的假设 .

请帮忙,因为我卡住了,不知道该怎么办

2 回答

  • 0

    如果要为任何事物动态分配存储空间,首先需要一个指向类型的指针 . 您使用 DynamicArray mArray; 声明了1个类型为 DynamicArray 的静态变量 . 相反,你需要 DynamicArray *mArray; ,你也可以将其初始化为 NULL

    int main (void) {
    
        /* Create my dynamic array of size 5 */
        DynamicArray *mArray = NULL;
        CreateArray (&mArray, 5);
    
        return 0;
    }
    

    由于您有一个指针,当您将地址发送到 CreateArray 时,funciton参数必须是双指针 . 然后在 CreateArray 中,要为 mArray 分配,必须取消引用作为参数传递的值并分配 *mArray = malloc... . 您也可以使用 calloc 代替 malloc ,这将为可忽略的额外开销量分配并将新的内存块初始化为零:

    /* Initialize the dynamic array */
    void CreateArray (DynamicArray **mArray, int initialSize)
    {
        /*  TODO: Use malloc to create an array of the initial size.
            Assign to the arrayPointer variable */
    
        /* using calloc will allocate & initialize to zero */
        *mArray = calloc (initialSize, sizeof **mArray);
    
        if (!(*mArray)) {
            fprintf (stderr, "CreateArray() error: virtual memory exhausted.\n");
            exit (EXIT_FAILURE);
        }
    
    }
    

    除非你有一些要求使用 void 类型的函数,为什么不返回指针呢?

    DynamicArray *CreateArray (DynamicArray **mArray, int initialSize)
    {
        /*  TODO: Use malloc to create an array of the initial size.
            Assign to the arrayPointer variable */
    
        /* using calloc will allocate & initialize to zero */
        *mArray = calloc (initialSize, sizeof **mArray);
    
        if (!(*mArray)) {
            fprintf (stderr, "CreateArray() error: virtual memory exhausted.\n");
            exit (EXIT_FAILURE);
            /* or you can now: 'return NULL;' instead of exiting. */
        }
    
        return *mArray;
    }
    

    最后,在你的动态分配内存的任何代码中,你有2个责任关于任何分配的内存块:(1)总是保留一个指向内存块起始地址的指针,所以,(2)它可以在它被释放时不再需要了 . 您还必须使用内存错误检查程序,以确保您没有在已分配的内存块之外/之外写入,并确认已释放已分配的所有内存 . 对于Linux valgrind 是正常的选择 . 有许多微妙的方法来滥用可能导致实际问题的内存块,没有理由不这样做 .

    Additional Example

    所以,你需要更多的帮助缝合它们 . 下面是一个简短的示例,它分配一个动态数组5 struct DynamicArray 并初始化元素 04 . 然后它打印 arrayPointer 指向的double数组中的值作为第4个元素,然后释放分配的内存 . 我还包括了编译字符串和valgrind内存错误检查:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define DASIZE 5
    
    typedef struct {
        double *arrayPointer;
        int effectiveSize;
        int maximumSize;
    } DynamicArray;
    
    void CreateArray (DynamicArray **mArray, int initialSize);
    
    int main (void) {
    
        double tmp[] = {0.0, 0.1, 0.2, 0.3};
        int i;
    
        /* Create my dynamic array of size 5 */
        DynamicArray *mArray = NULL;
        CreateArray (&mArray, DASIZE);
    
        /* assign pointer and values for element 0 */
        mArray[0].arrayPointer = tmp;
        mArray[0].effectiveSize = sizeof tmp/sizeof *tmp;
        mArray[0].maximumSize = mArray[0].effectiveSize;
    
        /* assign pointer and values for element 4 */
        mArray[4].arrayPointer = tmp;
        mArray[4].effectiveSize = sizeof tmp/sizeof *tmp;
        mArray[4].maximumSize = mArray[4].effectiveSize;
    
        /* print values for element 4 */
        printf ("\n information for mArray[4]:\n\n");
        printf ("   mArray[4].effectiveSize : %d\n", mArray[4].effectiveSize);
        printf ("   mArray[4].maximumSize   : %d\n\n", mArray[4].maximumSize);
        for (i = 0; i < mArray[4].effectiveSize; i++)
            printf ("   mArray[4].arrayPointer[%d] : %.1lf\n",
                    i, mArray[4].arrayPointer[i]);
    
        free (mArray);  /* free all memory allocated */
    
        putchar ('\n'); /* add an additional newline to make it look nice */
    
        return 0;
    }
    
    /* Allocate memory for dynamic array of struct */
    void CreateArray (DynamicArray **mArray, int initialSize)
    {
        /* using calloc will allocate & initialize to zero */
        *mArray = calloc (initialSize, sizeof **mArray);
    
        if (!(*mArray)) {
            fprintf (stderr, "CreateArray() error: virtual memory exhausted.\n");
            exit (EXIT_FAILURE);
        }
    }
    

    Compile

    gcc -Wall -Wextra -O2 -o bin/array_dyn_min array_dyn_min.c
    

    Use/Output

    $ ./bin/array_dyn_min
    
     information for mArray[4]:
    
       mArray[4].effectiveSize : 4
       mArray[4].maximumSize   : 4
    
       mArray[4].arrayPointer[0] : 0.0
       mArray[4].arrayPointer[1] : 0.1
       mArray[4].arrayPointer[2] : 0.2
       mArray[4].arrayPointer[3] : 0.3
    

    Memory/Error Check

    $ valgrind ./bin/array_dyn_min
    ==2232== Memcheck, a memory error detector
    ==2232== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
    ==2232== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
    ==2232== Command: ./bin/array_dyn_min
    ==2232==
    
     information for mArray[4]:
    
       mArray[4].effectiveSize : 4
       mArray[4].maximumSize   : 4
    
       mArray[4].arrayPointer[0] : 0.0
       mArray[4].arrayPointer[1] : 0.1
       mArray[4].arrayPointer[2] : 0.2
       mArray[4].arrayPointer[3] : 0.3
    
    ==2232==
    ==2232== HEAP SUMMARY:
    ==2232==     in use at exit: 0 bytes in 0 blocks
    ==2232==   total heap usage: 1 allocs, 1 frees, 80 bytes allocated
    ==2232==
    ==2232== All heap blocks were freed -- no leaks are possible
    ==2232==
    ==2232== For counts of detected and suppressed errors, rerun with: -v
    ==2232== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
    

    内存错误检查的重要行是:

    total heap usage: 1 allocs, 1 frees, 80 bytes allocated
    ...
    All heap blocks were freed -- no leaks are possible
    ...
    ERROR SUMMARY: 0 errors from 0 contexts...
    

    这告诉你有 '1' 动态内存分配和 '1' 空闲,并且释放了所有已分配的内存,并且在程序期间使用内存没有内存错误 . 您可以忽略(抑制:2从2),这是valgrind告诉您它缺少2个库的符号表(调试版本) . (在我的系统上,因为它们没有安装......)

  • 0

    这就是我要感谢你的一切

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct
    {
        double *arrayPointer;
        int effectiveSize;
        int maximumSize;
    } DynamicArray;
    
    void CreateArray(DynamicArray *mArray, int initialSize)
    {
        mArray->arrayPointer = (double *)malloc(sizeof(double) * initialSize);
        mArray->effectiveSize = 0;
        mArray->maximumSize = initialSize;
    }
    
    void ExpandArray(DynamicArray *mArray, int newSize)
    {
        double *newArray = (double *)malloc(sizeof(double) * newSize);
        memcpy(newArray, mArray->arrayPointer, sizeof(double) * mArray->maximumSize);
        free(mArray->arrayPointer);
        mArray->arrayPointer = newArray;
        mArray->maximumSize = newSize;
    }
    
    void AddValue(DynamicArray *mArray)
    {
        double input;
        printf("Enter a new value: ");
        scanf_s("%lf", &input);
    
        mArray->arrayPointer[mArray->effectiveSize] = input;
        mArray->effectiveSize++;
    
        if (mArray->effectiveSize == mArray->maximumSize)
        {
            printf("Expanding array from %d to %d\n", mArray->maximumSize, mArray->maximumSize * 2);
            ExpandArray(mArray, mArray->maximumSize * 2);
        }
    }
    
    void PrintArray(const DynamicArray *mArray)
    {
        int i;
        for (i = 0; i < mArray->effectiveSize; i++)
        {
            printf("%.2lf ", mArray->arrayPointer[i]);
        }
        printf("\n");
    }
    
    int main(void)
    {
        int i;
        DynamicArray mArray;
        CreateArray(&mArray, 5);
        for (i = 0; i < 5; i++)
        {
            AddValue(&mArray);
        }
        PrintArray(&mArray);
        for (i = 0; i < 5; i++)
        {
            AddValue(&mArray);
        }
        PrintArray(&mArray);
        system("pause");
    }
    

相关问题