Thread 1: EXC_BAD_ACCESS (code=1, address=0x0) standard C memory issue
Matthew Harrington
I'm writing code to compare two input files in standard C, using the Xcode IDE. I keep getting this error: Thread 1: EXC_BAD_ACCESS (code=1, address=0x0). I've done some reading on this and believe it to be a memory issue, but no matter what I try I can't seem to fix it (I've also tried making the structures dynamically using malloc and listed that at the bottom of the code). It's strange because it writes all of the data and then spits out that error at the end. The file format is something like this: start(int)..stop(int) id(+ or -) now some stuff I don't care about for the rest of the line I've just been testing this on a file with only + id's so the "-" aspect isn't part of the issue. Anyway I'm quite tired and have been staring at this for a few hours, so please forgive me if it doesn't make sense, I will update it after a few hours of sleep.
typedef struct
{ int start; int stop; char *strandID;
} location;
int main(int argc, const char * argv[])
{ if (argc != 4) { fprintf(stderr, "Usage is ./a.out windowfile.txt genefile.txt outputFileName"); exit(-1); } //const vars const char *windowInput = argv[1]; const char *geneInput = argv[2]; const char *outputfile = argv[3]; const int windowHeader = 9; const int geneHeader = 3; //get size of structures -- I have debugged and these work correctly, returning the size of my structure const int posWsize = getSize(windowInput, "+", windowHeader); const int negWsize = getSize(windowInput, "-", windowHeader); const int posGsize = getSize(geneInput, "+", geneHeader); const int negGsize = getSize(geneInput, "-", geneHeader); //declare structs location posWindow[posWsize]; location negWindow[negWsize]; location posGene[posGsize]; location negGene[negGsize]; //extract data here getLocations(posWindow, negWindow, windowInput, windowHeader); return 0;
}
void getLocations(location *posL, location *negL, const char *input, const int header)
{ FILE *fileptr = NULL; fileptr = fopen(input, "r"); //open file if (fileptr == NULL) { //check for errors while opening fprintf(stderr, "Error reading %s\n", input); exit(-1); } char tmpLoc[20]; char tmpID[2]; int eofVar = 0; int lineCount = 0; while (lineCount < header) { //skip header and get to data eofVar = fgetc(fileptr); if (eofVar == '\n') lineCount++; } int pCount = 0; int nCount = 0; while (eofVar != EOF) { fscanf(fileptr, "%s %s", tmpLoc, tmpID); //scan in first two strings if (!strcmp(tmpID, "+")) { //if + strand char *locTok = NULL; locTok = strtok(tmpLoc, ".."); //tok and get values posL[pCount].start = atoi(locTok); locTok = strtok(NULL, ".."); posL[pCount].stop = atoi(locTok); //ERROR IS SHOWN HERE posL[pCount].strandID = tmpID; printf("start=%d\tstop=%d\tID=%s\tindex=%d\n", posL[pCount].start, posL[pCount].stop, posL[pCount].strandID, pCount); pCount++; } else if (!strcmp(tmpID, "-")) { //if - strand char *locTok = NULL; locTok = strtok(tmpLoc, ".."); //tok and get values negL[nCount].start = atoi(locTok); locTok = strtok(NULL, ".."); negL[nCount].stop = atoi(locTok); negL[nCount].strandID = tmpID; nCount++; } while ((eofVar = fgetc(fileptr)) != '\n') { if (eofVar == EOF) break; } } fclose(fileptr);
}
//dynamic way...same issue -- just replace this with the above if statement and use the create location function
if (!strcmp(tmpID, "+"))
{ //if + strand int locStart; int locStop; locStart = atoi(strtok(tmpLoc, ".."));//tok and get values locStop = atoi(strtok(NULL, "..")); posL[pCount] = *createlocation(locStart, locStop, tmpID); pCount++;
}
location *createlocation(int start, int stop, char *strandID)
{ location *tmp = NULL; tmp = (location *) malloc(sizeof(location) * 1); tmp->start = start; tmp->stop = stop; tmp->strandID = (char *) malloc(sizeof(char) * 2); strcpy(tmp->strandID, strandID); return tmp;
} 6 5 Answers
Check the return value of strtok.
In your code here
locTok = strtok(NULL, "..");
posL[pCount].stop = atoi(locTok); //ERROR IS SHOWN HEREstrtok is returning a NULL pointer and according to documentation,
A null pointer is returned if there are no tokens left to retrieve.
which matches my original guess that because the address code is 0x0 there's a NULL pointer deference somewhere.
Obviously, the following call to atoi is expecting a non-NULL pointer and crashes.
You Can Also Use Exception Breakpoint in Xcode.
An exception breakpoint tells the debugger to pause whenever a problem is encountered anywhere in your program, so you can evaluate your program's state before it crashes.
Go to the Breakpoint Navigation (Cmd+8), then click the + button in the bottom left and choose Add Exception Breakpoint. You can leave it there.
for xc
in your main() function, try to remove char*argv[] or both arguments.
In my case, I was using the wrong block type. For some reason, a developer had marked a block as const id blockName = ^(Type variableName) { /* code */ } but unfortunately the Type mismatched . Because blockNamewas declared as typeid, the compiler could not warn me properly when I passed blockName` as an argument somewhere else, and this error happened at runtime instead.
For example:
const id callback = ^(ARTPaginatedResult<ARTMessage *> * _Nullable paginatedResult, ARTErrorInfo * _Nullable error) { /* code */ [channel setOptions:channelOptions callback:callback];The block above has 3 parameters, but channel:setOptions:callback: defines 1 argument called callback, which must be a block which takes 1 argument, and is declared as
- (void)setOptions:(ARTRealtimeChannelOptions *_Nullable)options callback:(nullable void (^)(ARTErrorInfo *_Nullable))cb; You should delete the arguments of you main function. And it will work.