Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - C Errore gestione dinamica della memoria
Forum - C/C++ - C Errore gestione dinamica della memoria

Avatar
Ale96 (Member)
Pro


Messaggi: 132
Iscritto: 06/04/2010

Segnala al moderatore
Postato alle 21:45
Giovedì, 02/02/2012
Buonasera,
Sto cercando di imparare ad un alto livello il linguaggio C tuttavia ora non sono ancora esperto, in questi giorni mi sto dedicando alla gestioni dinamica della memoria, quindi ho scritto un codice che dovrebbe rappresentare una lista di interi, decisamente inutile, ma è solo un esempio, questo è il codice (in inglese)
Codice sorgente - presumibilmente Delphi

  1. /* this is an example of dynamic memory allocation in C
  2.    it uses a dynamic array to store some value of a list
  3.    I've also included many functions to operate with the list.
  4. */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7.  
  8. #define UINT unsigned int
  9. #define UINTSIZE sizeof(UINT)
  10.  
  11. //Print an error message
  12. #define ERROR                                               \
  13.    {                                                       \
  14.        printf("ERROR OCCURRED AT LINE %d\n"                \
  15.               "Press any key to exit", __LINE__);          \
  16.        getch();                                            \
  17.        exit(-1);                                           \
  18.    }
  19. //Check if List is NULL, if it is print an error message
  20. #define CHECK(List)                                         \
  21.    {                                                       \
  22.        if (List == NULL)                                   \
  23.            ERROR                                           \
  24.    }
  25.  
  26.  
  27. /*
  28.    this structure represent a list of unsigned int
  29. */
  30. typedef struct{
  31.    UINT len;       //This is the number of elements
  32.    UINT * items;   //This is a pointer to the first element
  33. } DYNAMIC_UINT_LIST;
  34.  
  35.  
  36. //Prototypes
  37. void ListInitialize( DYNAMIC_UINT_LIST *, UINT);
  38. void ListDestroy(DYNAMIC_UINT_LIST *);
  39. void ListAppend(DYNAMIC_UINT_LIST *, UINT);
  40. void ListAdd(DYNAMIC_UINT_LIST *, UINT, UINT);
  41. void ListPrint(DYNAMIC_UINT_LIST);
  42.  
  43.  
  44.  
  45.  
  46. void ListInitialize(DYNAMIC_UINT_LIST * List, UINT FirstElement)
  47.    /*Initialize the list,
  48.    List is a pointer to the list we want to initialise, FirstElement is the first element to add.*/
  49. {
  50.    List->len = 1;
  51.    List->items = (UINT*)malloc( UINTSIZE );
  52.    CHECK(List->items);
  53.    *(List->items) = FirstElement;
  54. }
  55.  
  56. void ListDestroy(DYNAMIC_UINT_LIST *List)
  57. /*Free the memory, you have to call this method when you no longer use the list
  58.  after this call if you want to use the list you can, but you have to reinitialize it
  59.  List is a pointer to the list we want to destroy. */
  60. {
  61.    free(List->items); //Free the memory pointed by List->items, to avoid memory leak
  62. }
  63.  
  64. void ListAppend(DYNAMIC_UINT_LIST *List, UINT NewItem)
  65. /*Add the element NewItem at the end of the list pointed by List*/
  66. {
  67.    List->len++;
  68.    List->items = realloc(List->items, List->len * UINTSIZE);
  69.    //realloc doesn't modyfy the contents of the already existing elements in the array
  70.     CHECK(List->items);     //Check whether items is NULL, remember thet realloc, calloc and malloc return the null pointer on error
  71.     *(List->items + List->len - 1) = NewItem;   //Equivalent to List->items[List->len -1]
  72.                                                 // *(x + y) is the same as x[y], x must be a pointer and y a integer
  73. }
  74.  
  75. void ListAdd(DYNAMIC_UINT_LIST *List, UINT NewItem, UINT NewPos)
  76. /*Add the element NewItem in the list List at the position NewPos
  77. Where NewPos is the position of the new item in the list*/
  78. {
  79.     if (NewPos >= List->len + 1)
  80.         //Cannot add the new item
  81.         return;
  82.  
  83.     List->len++;
  84.     List->items = realloc(List->items, List->len * UINTSIZE);
  85.     CHECK(List->items); //the error is here because List->items is NULL
  86.                         //the output is ERROR OCCURRED AT LINE 86 and the pr€ogram ends
  87.     int CurrentPos;
  88.  
  89.     for (CurrentPos = List->len; CurrentPos > NewPos; CurrentPos--){
  90.         (*(List->items + CurrentPos)) = (*(List->items + (CurrentPos - 1)));
  91.     }
  92.  
  93.     *(List->items + NewPos) = NewItem;
  94. }
  95.  
  96. void ListPrint(DYNAMIC_UINT_LIST List)
  97. /*Pritnts every element in the list*/
  98. {
  99.     int pos;
  100.     for (pos = 0; pos < List.len; pos++)
  101.         printf("%u\n", *(List.items + pos)); // %u is to print unsigned
  102. }
  103.  
  104. int main()
  105. {
  106.     DYNAMIC_UINT_LIST list;     //Create a object of type DYNAMIC_UINT_LIST named list, this represent the list of UINT
  107.  
  108.     ListInitialize(&list, 0);   //initialize the list and its first element is 0
  109.     ListAppend(&list, 1);       //add elements at the end, this function doesn't give me problems
  110.     ListAppend(&list, 6);
  111.     ListAppend(&list, 7);
  112.     ListAppend(&list, 8);
  113.  
  114.     ListAdd(&list, 5, 2);       //add an element in the midde, if I call it one or two time it's all ok
  115.     ListAdd(&list, 4, 2);       //but when i call it three or more times it doesn't works
  116.     ListAdd(&list, 3, 2);
  117.     ListAdd(&list, 2, 2);
  118.  
  119.  
  120.     ListPrint(list);            //Print the element in the list
  121.     ListDestroy(&list);         //Free the memory
  122.     system("PAUSE");            //Wait for a key press
  123.     return 0;
  124. }


Quando l'ho provato ho ottenuto più volte questo output:
ERROR OCCURRED AT LINE 86
(non è un messaggio del sistema, l'ho fatto apposta per avvertirmi quando il puntatore è nullo)
Ho provato ad eseguire un debug con GDB e questo è il risultato:
Debugger name and version: GNU gdb 6.8
Child process PID: 6936
Program received signal SIGTRAP, Trace/breakpoint trap.
In ntdll!DbgUiConvertStateChangeStructure () (C:\Windows\system32\ntdll.dll)
seguendo mentalmente cosa fa il computer il mio codice sembra corretto, la mia domanda quindi è: perchè non funziona?
Ci tengo anche a precisare che sto compilando si Windows.

PM
Avatar
anthony015 (Member)
Pro


Messaggi: 116
Iscritto: 20/05/2011

Up
1
Down
V
Segnala al moderatore
Postato alle 15:09
Venerdì, 03/02/2012
Codice sorgente - presumibilmente C/C++

  1. for (CurrentPos = List->len; CurrentPos > NewPos; CurrentPos--){
  2.         (*(List->items + CurrentPos)) = (*(List->items + (CurrentPos - 1)));
  3.     }


devi fare CurrentPos = List->len - 1, altrimenti sarebbe come accedere alla posizione 5 di un array di dimensione 5...

Ultima modifica effettuata da anthony015 il 03/02/2012 alle 15:11
PM