2015-11-20 40 views
-3

到目前爲止,您已經創建了一個固定大小的靜態數組。動態數組可以使用structs和malloc()來改變它們的大小。 陣列滿時: 分配一個新的內存塊。 將數據從一個指針複製到另一個指針。 釋放舊指針。 將新指針指定給動態數組struct創建動態數組的C編程

您只需實現函數來初始化動態數組並展開動態數組。 請按照評論,看看你需要什麼代碼。 需要代碼的註釋有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

嗨franedu,歡迎! Stackoverflow不是一個代碼寫入服務。沒有[明確問題陳述](http://stackoverflow.com/help/mcve)的問題對其他讀者沒有用;看看你能否對你的問題更具體。 :)下面是一些其他的幫助頁面,讓你開始:[問一個好問題](http://stackoverflow.com/help/how-to-ask),[我應該避免問什麼類型的問題](http ://stackoverflow.com/help/dont-ask)和[我可以在這裏詢問什麼主題?](http://stackoverflow.com/help/on-topic) – binarysubstrate

+1

你應該看到'realloc'函數。請參閱:http://linux.die.net/man/3/realloc和http://stackoverflow.com/questions/3684288/understanding-realloc – ViniciusArruda

+0

這似乎是一個家庭作業的任務,因爲它開始說「Up到現在您已經創建了靜態數組「。這個問題的作者可能只是以第二人稱發言。 –

回答

0

如果你要動態地分配存儲任何東西,你首先需要一個指向類型。您聲明瞭1個類型爲DynamicArray的靜態變量與DynamicArray mArray;。相反,你需要DynamicArray *mArray;,你不妨把它初始化爲NULL

int main (void) { 

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

    return 0; 
} 

既然你有一個指針,當你發送地址CreateArray,該功能可按參數必須是雙指針。然後在CreateArray中,爲了分配mArray,您必須取消引用作爲參數傳遞的值並分配*mArray = malloc...。您還可以代替malloc這對於額外的開銷可以忽略不計金額將分配和初始化的內存爲零的新的塊使用calloc:除非你有一些要求使用void類型的功能可按

/* 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); 
    } 

} 

,爲什麼不返回指針呢?

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個responsibilites:(1)總是保留一個指針的起始地址的內存塊左右, (2)當它不再需要時,它可以被釋放。使用內存錯誤檢查程序也是必要的,以確保您沒有在分配的內存塊之外/之外編寫內容,並確認已釋放了您分配的所有內存。對於Linux valgrind是正常的選擇。濫用一塊可能導致真正問題的內存塊有很多微妙的方法,沒有理由不這樣做。

附加的例子

所以,你需要更多的幫助縫製它一起。這是一個簡短的例子,它分配一個動態數組5 struct DynamicArray並初始化元素04。然後,它將第二個元素的arrayPointer指向的double數組中的值打印出來,然後釋放分配的內存。我也包括編譯字符串和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個庫的符號表(調試版本)。 (我的系統上,因爲它們沒有安裝...)

+0

謝謝你,我明白這一點,你做,但它仍然不編譯正確IDK的爲什麼 – franedu

+0

看到更新的答案,我加了一個完整的,可編譯例子。請注意,如果您只是想分配類似'tmp'的內容來分配給'arrayPointer'成員,請告訴我 - 這對於涉及到一個stuct沒有什麼意義,但如果是這樣的話,那就是顯然要容易得多。 –

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"); 
}