C - segfault when trying to use strdup

4.5k views Asked by At

I've used strdup() in the past in the same way that I am using it here. I am passing token2 into strdup which is of type char * with a valid pointer in it, yet when I try to run the line "name = strdup(token2);" my program segfaults and I am quite unsure as to why. If anyone would be able to help me it would be greatly appreciated. I also realize that my code does not return a proper type yet, I am still working on writing all of it.

struct YelpDataBST* create_business_bst(const char* businesses_path, const char* reviews_path){

  if(fopen(businesses_path,"r") == NULL || fopen(reviews_path,"r") == NULL)
    return NULL;
  FILE* fp_bp = fopen(businesses_path, "r");
  FILE* fp_rp = fopen(reviews_path, "r");

  struct YelpDataBST* yelp = malloc(sizeof(struct YelpDataBST*));

  int ID = -1;
  int tempID;
  long int addressOffset;
  long int reviewOffset;
  char line[2000];
  char line2[2000];
  char temp[2000];
  char temp2[2000];
  char* token;
  char* token2;
  char* name;
  int len;

  BusList* busNode = NULL;
  BusList* busList = NULL;
  BusTree* busTreeNode = NULL;
  BusTree* busTree = NULL;

  ID = -1;
  tempID = 0;
  fgets(line,2000,fp_rp);
  fgets(line2,2000,fp_bp);
  fseek(fp_rp,0, SEEK_SET);
  fseek(fp_bp,0,SEEK_SET);
  int ct = 0;
  while(!feof(fp_rp)){

     len = strlen(line);
     token = strtok(line, "\t");
     //printf("line: %s\n", line);
     token2 = strtok(line2, "\t");
     tempID = atoi((char*)strdup(token));
     if(ct == 0){
       tempID = 1;
       ct++;
     }

  if((ID != tempID || (ID < 0)) && tempID != 0){
    if(tempID == 1)
      tempID = 0;
    token2 = strtok(NULL, "\t");
    //name = strdup(token2);
    reviewOffset = ftell(fp_rp);
    if(tempID != 0)
      reviewOffset -= len;
    addressOffset = ftell(fp_bp);
    ID = atoi((char*)strdup(token));
    busList = BusNode_insert(busList, addressOffset, reviewOffset); //replace with create node for tree
    token2 = strtok(NULL, "\t");
    token2 = strtok(NULL, "\t");
    token2 = strtok(NULL, "\t");
    token2 = strtok(NULL, "\t");
    token2 = strtok(NULL, "\t");
    token2 = strtok(NULL, "\n");
    fgets(line2,2000,fp_bp);
  }
  token = strtok(NULL, "\t");
  token = strtok(NULL, "\t");
  token = strtok(NULL, "\t");
  token = strtok(NULL, "\t");
  token = strtok(NULL, "\n");
  fgets(line,2000,fp_rp);

  } 

  //BusList_print(busList);

}
1

There are 1 answers

5
M.M On

strdup(token) segfaulting is most likely explained by token being NULL. (You don't need to strdup here anyway). Change that piece of code to:

if ( token == NULL )
{
    fprintf(stderr, "Invalid data in file.\n");
    exit(EXIT_FAILURE);  // or some other error handling
}

tempID = atoi(token);

However a greater problem with the surrounding code is that you are trying to use strtok twice at once. It maintains internal state and you can only have one strtok "in progress" at any one time. The second one cancels the first one. You'll have to redesign that section of code.


Also, while(!feof(fp_rp)) is wrong, and your yelp mallocs the wrong number of bytes (although in the code posted you never actually try to store anything in that storage, so it would not cause an error just yet).