18

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;
}
alk
  • 69,737
  • 10
  • 105
  • 255
zeus_masta_funk
  • 1,388
  • 2
  • 11
  • 34
  • The address code being `0x0` suggests a NULL pointer deference. – tangrs Oct 08 '13 at 05:37
  • 1
    Stacktrace or it didn't happen. Also the program doesn't compile so I cannot get my own stack trace. – trojanfoe Oct 08 '13 at 06:09
  • Did you run the code through the Xcode debugger? – dreamlax Oct 08 '13 at 07:26
  • @dreamlax I seemed to have fix issue but to answer your question I was using breakpoints to go through my code. I do not know how to use the Xcode debugger. Most of the resources I've looked up on that are only obj-c and I primarily use standard c for my work. If you know of any free resources on debugging standard c in Xcode I would love to see them! Thanks – zeus_masta_funk Oct 08 '13 at 16:42
  • 1
    @trojanfoe Sorry but I'm unfamiliar with stack trace. How would I do that in Xcode. – zeus_masta_funk Oct 08 '13 at 16:45
  • it May Sound Weird But Clean Build Solved this error for me. – Govani Dhruv Vijaykumar May 04 '20 at 07:44

5 Answers5

6

Check the return value of strtok.

In your code here

locTok = strtok(NULL, "..");
posL[pCount].stop = atoi(locTok); //ERROR IS SHOWN HERE

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

tangrs
  • 9,709
  • 1
  • 38
  • 53
  • At the end of my 2nd while loop in getLocations, the stream goes only until the newline character. So it would scan in all of the data, get to the eof, then go through the while loop one more time. That caused scanf to scan in EOF for the first string and NULL for the second, causing an error in the second atoi conversion. I fixed it by adding 'eofVar = fgetc(fileptr);//check for eof if (eofVar == EOF) break; else eofVar = ungetc(eofVar, fileptr);' after scanning to the end of the line. If you have a more efficient method let me know! Thanks again. – zeus_masta_funk Oct 08 '13 at 16:37
4

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.

enter image description here

ZAFAR007
  • 3,049
  • 1
  • 34
  • 45
0

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;
Ben Butterworth
  • 22,056
  • 10
  • 114
  • 167
-1

for xc

in your main() function, try to remove char*argv[] or both arguments.

  • Hi there, welcome to SO. Your post is missing crucial details and it isn't ibvious what you need help with. Why don't you paste a code example? [Here's SO guide on asking good questions](https://stackoverflow.com/help/how-to-ask) – Konrads May 12 '20 at 03:46
-4

You should delete the arguments of you main function. And it will work.