0 Members and 1 Guest are viewing this topic.
Q: What kind of error in my program usually causes an "Address Error"? A: Well, writing over the boundaries of an array can usually cause all sorts of errors, since it usually destroys code or the return address of the function. However, an "Address Error" actually means that a short or long value is read or written at an odd address. So if you get an "Address Error" while you are dealing with pointers, check that you do not cast an odd address to a pointer to a short or long integer.
:BoxPlot\0x05\0:ClrHome\0xE1\0
void initTokens(tokenInfo *tokens, char *tokenfile){ int length; int bool; int newlength; int span = 0; int i = 0; char newchar; char endline = '\r'; unsigned long rawhex; unsigned short size = 0; unsigned char hex = '0'; char *tokentext = NULL; char *working = NULL; char *line = NULL; char *tokenstr = NULL; tokenInfo token; SYM_ENTRY *sym; if ((working = (char *)calloc(2, sizeof(char))) == NULL) { DlgMessage("DMA Failure", "Unable to allocate space for working string", BT_OK, BT_NONE); return; } if ((line = (char *)calloc(10, sizeof(char))) == NULL) { DlgMessage("DMA Failure", "Unable to allocate space for line string", BT_OK, BT_NONE); free(working); return; } if ((tokenstr = (char *)calloc(16, sizeof(char))) == NULL) { DlgMessage("DMA Failure", "Unable to allocate space for token working string", BT_OK, BT_NONE); free(working); free(line); return; } //Get the size of the token file and allocate memory accordingly sym = SymFindPtr(SYMSTR(tokenfile), 0); size = ((MULTI_EXPR*)HeapDeref(sym->handle))->Size + 2; if ((tokentext = (char *)calloc(size, sizeof(char))) == NULL) { DlgMessage("DMA Failure", "Unable to allocate space for token file string", BT_OK, BT_NONE); free(working); free(line); free(tokenstr); return; } //Get input from file, set length and reallocate memory to troublesome pointers bool = getPrgmFromText(tokenfile, tokentext, size); if (bool == 0) { free(tokentext); free(working); free(line); return; } length = strlen(tokentext); line = (char *)realloc(line, (length + 2) * sizeof(char)); tokenstr = (char *)realloc(tokenstr, (length + 2) * sizeof(char)); //Loop until the length of the input string is zero while (length > 0) { //Maintain num token size! i += 1; if (i > NUM_TOKENS) { tokens = (tokenInfo *)realloc(tokens, i * sizeof(tokenInfo)); NUM_TOKENS = i; } //Get the length of the line up to trailing character, reallocate memory memset(working, '\0', strlen(working)); memset(line, '\0', strlen(line)); memset(tokenstr, '\0', strlen(tokenstr)); sprintf(working, "%c", endline); span = strcspn(tokentext, working); //Load the line into a string, and then remove it line = strncat(line, tokentext, span); tokentext = strpbrk(tokentext, working); //Then clear out the \r at the front of the string and clear the working string out newchar = tokentext[2]; sprintf(working, "%c", newchar); tokentext = strpbrk(tokentext, working); length = strlen(tokentext); //Init the token token = tokens[i]; token.twoByteToken = 0; //Seperate the name component from the line and set it (and it's length!) memset(working, '\0', strlen(working)); sprintf(working, "%c", '\\'); newlength = strcspn(line, working); tokenstr = strncat(tokenstr, line, newlength); line += (newlength + 1); token.chars = newlength; token.name = tokenstr; //Seperate the hex component from the line and set it memset(tokenstr, '\0', strlen(tokenstr)); tokenstr = strncat(tokenstr, line, 4); rawhex = strtol(tokenstr, NULL, 0); hex = (unsigned char)rawhex; token.hex[0] = hex; line += 5; //Then check if what's left of the string is the second byte of a two-byte token and deal with it if (line[0] != '0') { rawhex = strtol(tokenstr, NULL, 0); ngetchx(); hex = (unsigned char)rawhex; token.hex[1] = hex; token.twoByteToken = 1; } //Update the token tokens[i] = token; } //Free memory free(working); free(tokenstr); free(line); free(tokentext);}
Stylistically speaking, DMA usually stands for "Direct Memory Access" instead of "Dynamic Memory Allocation"
It's often hard to debug a program with just one function, could you upload the source somewhere so that we can 1) look at the full source, 2) compile it and 3) execute it?
The advice given in the GCC4TI docs is "preserve the original pointer and pass it to free". How would I do this? Make a function and pass the code where I'm manipulating the pointer there?
type * orig_ptr = malloc/calloc(size);type * ptr = orig_ptr;<do something with ptr, leave orig_ptr alone>free(orig_ptr);