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