Oppure

Loading
02/02/12 20:45
Ale96
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)
/* this is an example of dynamic memory allocation in C
   it uses a dynamic array to store some value of a list
   I've also included many functions to operate with the list.
*/
#include <stdio.h>
#include <stdlib.h>

#define UINT unsigned int
#define UINTSIZE sizeof(UINT)

//Print an error message
#define ERROR                                               \
    {                                                       \
        printf("ERROR OCCURRED AT LINE %d\n"                \
               "Press any key to exit", __LINE__);          \
        getch();                                            \
        exit(-1);                                           \
    }
//Check if List is NULL, if it is print an error message
#define CHECK(List)                                         \
    {                                                       \
        if (List == NULL)                                   \
            ERROR                                           \
    }


/*
    this structure represent a list of unsigned int
*/
typedef struct{
    UINT len;       //This is the number of elements
    UINT * items;   //This is a pointer to the first element
} DYNAMIC_UINT_LIST;


//Prototypes
void ListInitialize( DYNAMIC_UINT_LIST *, UINT);
void ListDestroy(DYNAMIC_UINT_LIST *);
void ListAppend(DYNAMIC_UINT_LIST *, UINT);
void ListAdd(DYNAMIC_UINT_LIST *, UINT, UINT);
void ListPrint(DYNAMIC_UINT_LIST);




void ListInitialize(DYNAMIC_UINT_LIST * List, UINT FirstElement)
    /*Initialize the list,
    List is a pointer to the list we want to initialise, FirstElement is the first element to add.*/
{
    List->len = 1;
    List->items = (UINT*)malloc( UINTSIZE );
    CHECK(List->items);
    *(List->items) = FirstElement;
}

void ListDestroy(DYNAMIC_UINT_LIST *List)
/*Free the memory, you have to call this method when you no longer use the list
  after this call if you want to use the list you can, but you have to reinitialize it
  List is a pointer to the list we want to destroy. */
{
    free(List->items); //Free the memory pointed by List->items, to avoid memory leak
}

void ListAppend(DYNAMIC_UINT_LIST *List, UINT NewItem)
/*Add the element NewItem at the end of the list pointed by List*/
{
    List->len++;
    List->items = realloc(List->items, List->len * UINTSIZE);
    //realloc doesn't modyfy the contents of the already existing elements in the array
    CHECK(List->items);     //Check whether items is NULL, remember thet realloc, calloc and malloc return the null pointer on error
    *(List->items + List->len - 1) = NewItem;   //Equivalent to List->items[List->len -1]
                                                // *(x + y) is the same as x[y], x must be a pointer and y a integer
}

void ListAdd(DYNAMIC_UINT_LIST *List, UINT NewItem, UINT NewPos)
/*Add the element NewItem in the list List at the position NewPos
Where NewPos is the position of the new item in the list*/
{
    if (NewPos >= List->len + 1)
        //Cannot add the new item
        return;

    List->len++;
    List->items = realloc(List->items, List->len * UINTSIZE);
    CHECK(List->items); //the error is here because List->items is NULL
                        //the output is ERROR OCCURRED AT LINE 86 and the pr€ogram ends
    int CurrentPos;

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

    *(List->items + NewPos) = NewItem;
}

void ListPrint(DYNAMIC_UINT_LIST List)
/*Pritnts every element in the list*/
{
    int pos;
    for (pos = 0; pos < List.len; pos++)
        printf("%u\n", *(List.items + pos)); // %u is to print unsigned
}

int main()
{
    DYNAMIC_UINT_LIST list;     //Create a object of type DYNAMIC_UINT_LIST named list, this represent the list of UINT

    ListInitialize(&list, 0);   //initialize the list and its first element is 0
    ListAppend(&list, 1);       //add elements at the end, this function doesn't give me problems
    ListAppend(&list, 6);
    ListAppend(&list, 7);
    ListAppend(&list, 8);

    ListAdd(&list, 5, 2);       //add an element in the midde, if I call it one or two time it's all ok
    ListAdd(&list, 4, 2);       //but when i call it three or more times it doesn't works
    ListAdd(&list, 3, 2);
    ListAdd(&list, 2, 2);


    ListPrint(list);            //Print the element in the list
    ListDestroy(&list);         //Free the memory
    system("PAUSE");            //Wait for a key press
    return 0;
}

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.
aaa
03/02/12 14:09
anthony015
for (CurrentPos = List->len; CurrentPos > NewPos; CurrentPos--){
        (*(List->items + CurrentPos)) = (*(List->items + (CurrentPos - 1)));
    }

devi fare CurrentPos = List->len - 1, altrimenti sarebbe come accedere alla posizione 5 di un array di dimensione 5...
Ultima modifica effettuata da anthony015 03/02/12 14:11
aaa