到目前为止,您已经创建了一个固定大小的静态数组。 动态数组可以使用结构和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");
}
图片是它的假设。
请帮忙,因为我被困住了,不知道该怎么做
答案 0 :(得分:0)
如果要为任何事物动态分配存储空间,首先需要一个指向类型的指针。您使用DynamicArray
声明了DynamicArray mArray;
类型的1个静态变量。相反,您需要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
是正常的选择。有许多微妙的方法来滥用可能导致实际问题的内存块,没有理由不这样做。
附加示例
所以,你需要更多帮助缝合它们。下面是一个简短的示例,它分配5 struct DynamicArray
的动态数组并初始化元素0
和4
。然后,它将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);
}
}
<强>编译强>
gcc -Wall -Wextra -O2 -o bin/array_dyn_min array_dyn_min.c
使用/输出强>
$ ./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
内存/错误检查
$ 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个库的符号表(调试版本)。 (在我的系统上,因为它们没有安装......)
答案 1 :(得分: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");
}