2015-11-20 1 views
-3

Jusqu'à présent, vous avez créé des tableaux statiques, de taille fixe. Les tableaux dynamiques peuvent utiliser des structures et malloc() pour changer leur taille. Lorsque le tableau est plein: Allouer un nouveau bloc de mémoire. Copiez les données d'un pointeur à l'autre. Libère l'ancien pointeur. Affectation du nouveau pointeur à la structure du tableau dynamiqueProgrammation en C créant un tableau dynamique

Il suffit d'implémenter les fonctions pour initialiser la matrice dynamique et étendre la matrice dynamique. Suivez les commentaires pour voir ce que vous devez coder. Les commentaires qui ont besoin de code ont TODO: écrits en eux memcpy (void * dest, void * src, int octets) Une fonction utile pour copier la mémoire entre les pointeurs. Paramètre 1: pointeur de destination que vous copiez. Paramètre 2: pointeur source à partir duquel vous copiez. Paramètre 3: nombre d'octets à copier

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

l'image est de savoir comment son supposons ressembler.

S'il vous plaît aider comme je suis coincé et ne sais pas quoi faire

+0

Salut franedu, bienvenue! Stackoverflow n'est pas un service d'écriture de code. Les questions sans [énoncé de problème clair] (http://stackoverflow.com/help/mcve) ne sont pas utiles aux autres lecteurs; voyez si vous pouvez être plus précis avec votre question. :) Voici d'autres pages d'aide pour vous aider à démarrer: [Poser une bonne question] (http://stackoverflow.com/help/how-to-ask), [Quels types de questions dois-je éviter de demander] (http : //stackoverflow.com/help/dont-ask), et [Quels sujets puis-je poser à propos ici?] (http://stackoverflow.com/help/on-topic) – binarysubstrate

+1

Vous devriez voir la fonction 'realloc'. Voir: http://linux.die.net/man/3/realloc et http://stackoverflow.com/questions/3684288/understanding-realloc – ViniciusArruda

+0

Cela semble être un devoir, étant donné qu'il commence par dire "Up maintenant vous avez créé des tableaux statiques ". Il est possible que l'auteur de la question parle simplement à la deuxième personne. –

Répondre

0

Si vous allez allouer dynamiquement le stockage pour quoi que ce soit, vous devez d'abord un pointeur de type. Vous avez déclaré 1 variable statique de type DynamicArray avec DynamicArray mArray;. Au lieu de cela vous avez besoin DynamicArray *mArray; et vous pouvez ainsi l'initialiser à NULL:

int main (void) { 

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

    return 0; 
} 

Puisque vous avez un pointeur, lorsque vous envoyez l'adresse à CreateArray, le paramètre funciton doit être un double pointeur. Ensuite, dans CreateArray, pour allouer mArray, vous devez déréférencer la valeur passée en tant qu'argument et allouer *mArray = malloc.... Vous pouvez également utiliser calloc en place de malloc qui, pour une quantité négligeable des frais généraux supplémentaires allouera et initialiser le nouveau bloc de mémoire à zéro:

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

} 

Sauf si vous avez une obligation d'utiliser un type void pour le funciton, pourquoi ne pas retourner le pointeur?

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

Enfin, dans tout code de votre écriture qui alloue dynamiquement la mémoire, vous avez 2 RESPONSABILITES concernant un bloc de mémoire allouée: (1) conserve toujours un pointeur vers l'adresse de départ pour le bloc de mémoire ainsi, (2) il peut être libéré quand il n'est plus nécessaire. Il est également impératif que vous utilisiez un programme de vérification des erreurs de mémoire pour vous assurer que vous n'avez pas écrit au-delà/en dehors du bloc de mémoire alloué et pour confirmer que vous avez libéré toute la mémoire que vous avez allouée. Pour Linux valgrind est le choix normal. Il y a tellement de façons subtiles d'abuser d'un bloc de mémoire qui peut causer de vrais problèmes, il n'y a pas d'excuse pour ne pas le faire.

supplémentaires Exemple

, vous avez besoin d'un peu plus d'aide à coudre tous ensemble.Voici un court exemple qui alloue un tableau dynamique de 5 struct DynamicArray et initialise les éléments 0 et 4. Il imprime ensuite les valeurs dans le double tableau pointé par arrayPointer pour le 4ème élément, puis libère la mémoire allouée. J'ai également inclus la chaîne de compilation et l'erreur mémoire valgrind vérification:

#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 

Utilisation/sortie

$ ./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 

Mémoire/Contrôle d'erreur

$ 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) 

Les lignes importantes pour le contrôle d'erreur de mémoire sont:

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... 

Ce qui vous dit qu'il y avait '1' allocation dynamique de mémoire et '1' libre, et que toute la mémoire allouée a été libéré, et il n'y avait pas d'erreurs de mémoire avec l'utilisation de la mémoire pendant le programme. Vous pouvez ignorer le (supprimé: 2 de 2) qui est valgrind vous indiquant qu'il manque les tables de symboles (versions de débogage) de 2 bibliothèques. (Sur mon système, car ils ne sont pas installés ...)

+0

Merci je vois le point que vous faites, mais il ne compile pas encore idk droite pourquoi – franedu

+0

Voir la réponse mise à jour, j'ai ajouté un exemple complet et compilable. Remarquez, si vous étiez juste supposé allouer quelque chose comme 'tmp' à assigner au membre' arrayPointer', faites le moi savoir - cela n'aurait pas beaucoup de sens d'avoir une implication, mais si c'est le cas, c'est évidemment beaucoup plus facile. –

0

Voici ce que j'avais tocome avec vous remercier

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