Thread: Memory issue with new[] and delete[]

  1. #1
    Registered User
    Join Date
    Jul 2004
    Posts
    27

    Memory issue with new[] and delete[]

    Code:
      fseek(handle, 0, SEEK_END);
      int filesize = ftell(handle);
      rewind (handle);
      char* file_buffer = new char[filesize + 1];
      fread (file_buffer, filesize, 1, handle);
      file_buffer = strchr(file_buffer, '\n') + 1;
      file_buffer = strchr(file_buffer, '\n') + 1;
      delete[] file_buffer;
    At that delete occurs a segmentation fault. I don't understand why, and it's increasingly agrivating as I've been dealing with this for hours and now the variable I need to be able to clear has this same issue.

    it is NOT a lack of memory problem
    it is NOT a lack of space assigned, I've tried everything from just the filesize to +1500, and this file is a 63byte file o_0

    I highly doubt it's a problem from somewhere other than there, but here is the rest of the function at least...
    Code:
    int config::set_dest () {
      // Load the file and cut it down to the dest section
      fseek(handle, 0, SEEK_END);
      int filesize = ftell(handle);
      rewind (handle);
      char* file_buffer = new char[filesize + 1500];
      fread (file_buffer, filesize, 1, handle);
      file_buffer = strchr(file_buffer, '\n') + 1;
      file_buffer = strchr(file_buffer, '\n') + 1;
      int loop;
      char* tracker = new char[strlen(file_buffer) + 1500];
      if (strcpy(tracker, file_buffer) == NULL) {
        delete[] tracker;
        delete[] file_buffer;
        return -1;
      }
      for (loop = 1; tracker = strchr(tracker, '\n'); loop++) {
        tracker++;
        if (strchr(tracker, '\n') == NULL) {
          if (strlen(tracker) > 0)
            loop++;
          break;
        }
        if (strlen(tracker) == strlen(strchr(tracker, '\n')))
          loop--;
      }
      dest_num = loop;
      if (dest_num < 1) {
        delete[] tracker;
        delete[] file_buffer;
        return -2;
      }
      dest = new char*[dest_num];
      delete[] tracker; //Seg fault
      tracker = new char[strlen(file_buffer) - strlen(strchr(strchr(file_buffer, '\n') + 1, '\n')) + 1];
      if (strncpy(tracker, strchr(file_buffer, '\n') + 1, strlen(file_buffer) - strlen(strchr(strchr(file_buffer, '\n') + 1, '\n'))) == NULL) {
        delete[] tracker;
        delete[] file_buffer;
        return -1;
      }
      delete[] file_buffer; // Seg fault
      for (loop = 1; loop <= dest_num; loop++) {
        if (strchr(tracker, '\n') != NULL) {
          if (strlen(tracker) != strlen(strchr(tracker, '\n'))) {
            dest[loop - 1] = new char[strlen(tracker) - strlen(strchr(tracker, '\n'))];
    	strncpy(dest[loop - 1], tracker, strlen(tracker) - strlen(strchr(tracker, '\n')));
    	tracker = strchr(tracker, '\n') + 1;
          } else {
            tracker++;
    	loop--;
    	continue;
          }
        } else {
          printf ("%i", strlen(tracker));
        }
      }
      for (loop = 0; loop < dest_num; loop++)
        printf ("dest[%i]: %s\n", loop, dest[loop]);
    
      return 0;
    }

  2. #2
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Ok how about saying what the actually problem is

  3. #3
    Registered User
    Join Date
    Jul 2004
    Posts
    27
    A segmentation fault occurs...
    I wish I knew why, but I don't. -_-
    That's what I'm asking... x_X

    (It's a runtime issue, program compiles fine...)

  4. #4
    Crazy Fool Perspective's Avatar
    Join Date
    Jan 2003
    Location
    Canada
    Posts
    2,640
    el hint...
    $man strchr
    [...]
    RETURN VALUE
    The strchr() and strrchr() functions return a pointer to the matched
    character or NULL if the character is not found.
    [...]
    i havent looked too much at your code but id suggest using a different char* to catch the return value of strchr.

  5. #5
    Registered User
    Join Date
    Jul 2004
    Posts
    27
    I did try that.. It didn't fix the issue...

    I am only using pointers to new char[]'s for this program, could that be an issue? Using only dynamic memory for strings?

  6. #6
    Crazy Fool Perspective's Avatar
    Join Date
    Jan 2003
    Location
    Canada
    Posts
    2,640
    Quote Originally Posted by Zarkhalar
    I did try that.. It didn't fix the issue...

    I am only using pointers to new char[]'s for this program, could that be an issue? Using only dynamic memory for strings?
    no.

    try adding a null terminator to the end of your strings.

  7. #7
    Registered User
    Join Date
    Jul 2004
    Posts
    27
    Code:
      char* file_buffer = new char[filesize + 1];
      fread (file_buffer, filesize, 1, handle);
      file_buffer[filesize + 1] = '\0';
    
      file_buffer = strchr(file_buffer, '\n') + 1; file_buffer[strlen(file_buffer) + 1] = '\0';
      file_buffer = strchr(file_buffer, '\n') + 1; file_buffer[strlen(file_buffer) + 1] = '\0';
      delete[] file_buffer;
    Still gives me a segmentation fault.

    I really don't care about any of the other code right now. I haven't even gotten to where I need this program to be, I'm so stuck on this stupid parser o_0; PHP strings are much easier to deal with :P

    I just want to know why this is crashing like this? Is it because of the multiple pointers possibly, if it isn't the memory? I doubt I'd have this problem with malloc x_X

    edit: Nevermind, malloc gives me the same fault at the same time -_-
    Last edited by Zarkhalar; 08-04-2004 at 08:20 PM.

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Well, you're wandering off past the end of your array here:
    Code:
    file_buffer[filesize + 1] = '\0';
    Oh, and here:
    Code:
    ...; file_buffer[strlen(file_buffer) + 1] = '\0';
    ...; file_buffer[strlen(file_buffer) + 1] = '\0';
    Not to mention, you're deleting the same memory twice:
    Code:
    if (strncpy(tracker, strchr(file_buffer, '\n') + 1, ...) {
        delete[] tracker;
        delete[] file_buffer;
        return -1;
      }
      delete[] file_buffer; // Seg fault
    Fix all of that, then try again and maybe I'll read some more of your code.

    [edit=doh]
    Doh. I didn't see your "return -1" in there. Ignore the last one. I didn't register that line. I was thinking you called delete, then it dropped out of the IF check, and called it again.
    [/edit]

    Quzah.
    Last edited by quzah; 08-04-2004 at 09:10 PM.
    Hope is the first step on the road to disappointment.

  9. #9
    Registered User
    Join Date
    Jul 2004
    Posts
    27
    All those things you just mentioned were mostly tests, except for the last codebox you put, which is an if statement in case something messes up in the program it gets rid of the memory first just in case...

    Do the compilers consider the memory deleted instantly when it's in a if statement, or will it not delete the memory until that if statement is called?

  10. #10
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    Quzah: I agree with the out of bounds part but--

    Code:
    if (strncpy(tracker, strchr(file_buffer, '\n') + 1, ...) {
    	delete[] tracker;
    	delete[] file_buffer;
    	return -1;
    }
    delete[] file_buffer; // Seg fault
    doesn't the return statement within the body of the if statement mean that one and only one of the lines:

    delete[] file_files

    will ever be called? If the return statement is encountered all the code below the if statement is irrelevant and will never be seen during run-time and if the return statement isn't seen then neither can the first call to the delete operator for this memory collection because the first call to delete and the return statement are both within the same scope. Therefore, in the above snippet the memory assigned to file_buffer is gauranteed to be deleted once, and only once.

  11. #11
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by elad
    doesn't the return statement within the body of the if statement mean that one and only one of the lines:

    delete[] file_files

    will ever be called?
    Yep. See edit.

    Quzah.
    Hope is the first step on the road to disappointment.

  12. #12
    Registered User
    Join Date
    Jul 2004
    Posts
    27
    Again, here is the real code, fully commented
    Code:
      fseek(handle, 0, SEEK_END); // Goes to the end possition in the file.
      int filesize = ftell(handle); // gets the length of the file.
      rewind (handle); // Goes back to the start of the file
      char* file_buffer = new char[filesize]; // a new dynamic memory variable
      fread (file_buffer, filesize, 1, handle); // Reads a small file into the new variable
      file_buffer = strchr(file_buffer, '\n') + 1; // Goes the the closest new line, then goes one point forward in the pointer to go past it so I can...
      file_buffer = strchr(file_buffer, '\n') + 1; // Go down another line, then I pass it
      delete[] file_buffer; // Now I delete the buffer. This isn't suppose to be here in the real code, but weather its at the bottom or here, this is the line that cuases the segment fault
    This entire program is a big couple classes with variables and int functions, and the only thing the main function does is error handle the returns. It's basically a 300 line parser for a small file, but I wanted to make it more or less idiot proof ;P. There is another function right above this one that does similar stuff, no problems.. Here are both the whole functions (the set_dest one may not be completely accurate because I've been trying to fix it x_X)

    Code:
    int config::set_exempt (const char* delimiter) {
      // Load the file and cut it down to the exempt line only
      fseek(handle, 0, SEEK_END);
      int filesize = ftell(handle);
      rewind (handle);
      char* file_buffer = new char[filesize];
      fread (file_buffer, filesize, 1, handle);
      file_buffer = strchr(file_buffer, '\n') + 1;
      if (strchr(file_buffer, '\n') == NULL) {
        delete[] file_buffer;
        return -1;
      }
      if (strlen(file_buffer) == strlen(strchr(file_buffer, '\n'))) {
        delete[] file_buffer;
        return -2;
      }
      char* tracker = new char[strlen(file_buffer) - strlen(strchr(file_buffer, '\n')) + 1];
      if (strlen(file_buffer) - strlen(strchr(file_buffer, '\n')) != strlen(delimiter)) {
        strncpy (tracker, file_buffer, strlen(file_buffer) - strlen(strchr(file_buffer, '\n'))); // Keep file_buffer for later
      } else {
        delete[] file_buffer;
        delete[] tracker;
        return -3;
      }
    
      if (strlen(tracker) == strlen(strstr(tracker, delimiter)))
        tracker += strlen(delimiter);
      int loop;
      for (loop = 1; tracker = strstr(tracker, delimiter); loop++) {
        if (strlen(delimiter) == strlen(tracker)) {
          break;
        }
        // Try to add it so it minus's a delimiter when two are in a row :/
        tracker += strlen(delimiter);
      }
      // Reset tracker, set exempt and exempt_num
      delete[] tracker;
      tracker = new char[strlen(file_buffer) - strlen(strchr(file_buffer, '\n')) + 1];
      strncpy (tracker, file_buffer, strlen(file_buffer) - strlen(strchr(file_buffer, '\n')));
      delete[] file_buffer;
      exempt_num = loop;
      exempt = new char*[exempt_num];
      if (strlen(tracker) == strlen(strstr(tracker, delimiter)))
        tracker += strlen(delimiter);
      for (loop = 1; loop <= exempt_num; loop++) {
        if (strstr(tracker, delimiter)) {
          exempt[loop - 1] = new char[strlen(tracker) - strlen(strstr(tracker, delimiter)) + 1];
          if (strncpy (exempt[loop - 1], tracker, strlen(tracker) - strlen(strstr(tracker, delimiter))) == NULL) {
            delete[] tracker;
            delete[] exempt;
            return -4;
          }
        } else {
          exempt[loop - 1] = new char[strlen(tracker) + 1];
          if (strcpy(exempt[loop - 1], tracker) == NULL) {
            delete[] tracker;
    	delete[] exempt;
    	return -4;
          }
        }
        if (strstr(tracker, delimiter) != NULL) {
          tracker = strstr(tracker, delimiter);
          tracker += strlen(delimiter);
        }
      }
      delete[] tracker;
      return 0;
    }
    
    int config::set_dest () {
      // Load the file and cut it down to the dest section
      fseek(handle, 0, SEEK_END);
      int filesize = ftell(handle);
      rewind (handle);
      char* file_buffer = new char[filesize + 1];
      fread (file_buffer, filesize, 1, handle);
      file_buffer = strchr(file_buffer, '\n') + 1;
      file_buffer = strchr(file_buffer, '\n') + 1;
      delete[] file_buffer;
    
      int loop;
      char* tracker = new char[strlen(file_buffer) + 1500];
      if (strcpy(tracker, file_buffer) == NULL) {
        delete[] tracker;
        delete[] file_buffer;
        return -1;
      }
      for (loop = 1; tracker = strchr(tracker, '\n'); loop++) {
        tracker++;
        if (strchr(tracker, '\n') == NULL) {
          if (strlen(tracker) > 0)
            loop++;
          break;
        }
        if (strlen(tracker) == strlen(strchr(tracker, '\n')))
          loop--;
      }
      dest_num = loop;
      if (dest_num < 1) {
        delete[] tracker;
        delete[] file_buffer;
        return -2;
      }
      dest = new char*[dest_num];
      //delete[] tracker;
      tracker = new char[strlen(file_buffer) - strlen(strchr(strchr(file_buffer, '\n') + 1, '\n')) + 1];
      if (strncpy(tracker, strchr(file_buffer, '\n') + 1, strlen(file_buffer) - strlen(strchr(strchr(file_buffer, '\n') + 1, '\n'))) == NULL) {
        delete[] tracker;
        delete[] file_buffer;
        return -1;
      }
      //delete[] file_buffer;
      for (loop = 1; loop <= dest_num; loop++) {
        if (strchr(tracker, '\n') != NULL) {
          if (strlen(tracker) != strlen(strchr(tracker, '\n'))) {
            dest[loop - 1] = new char[strlen(tracker) - strlen(strchr(tracker, '\n'))];
    	strncpy(dest[loop - 1], tracker, strlen(tracker) - strlen(strchr(tracker, '\n')));
    	tracker = strchr(tracker, '\n') + 1;
          } else {
            tracker++;
    	loop--;
    	continue;
          }
        } else {
          printf ("%i", strlen(tracker));
        }
      }
     
      return 0;
    }

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    How about
    Code:
      int filesize = ftell(handle); // gets the length of the file.
      rewind (handle); // Goes back to the start of the file
      char* file_buffer = new char[filesize+1]; // a new dynamic memory variable +1 for the \0
      fread (file_buffer, filesize, 1, handle); // Reads a small file into the new variable
      file_buffer[filesize] = '\0';
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  14. #14
    Registered User
    Join Date
    Jul 2004
    Posts
    27
    Code:
      char* file_buffer = new char[filesize + 1];
      fread (file_buffer, filesize, 1, handle);
      file_buffer[filesize] = '\0';
      file_buffer = strchr(file_buffer, '\n') + 1;
      file_buffer = strchr(file_buffer, '\n') + 1;
      delete[] file_buffer;
    Segmentation fault yet again...
    I don't get the faults if I don't do two of the strchr's, but I need to get down two lines in this x_X

    edit: Oddly enough, if I make the last strchr + 1 to strchr + 2, I don't get a segmentation fault...

    I'm just going to rewrite the parser, prolly end up a lot smaller too x_X

    Thanks for the help guys =).
    Last edited by Zarkhalar; 08-05-2004 at 07:49 AM.

  15. #15
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    You need to use a temporary buffer.
    Code:
      char* file_buffer = new char[filesize + 1];
      char *temp_buffer;
      
      fread (file_buffer, filesize, 1, handle);
      file_buffer[filesize] = '\0';
      temp_buffer = strchr(file_buffer, '\n') + 1;
      temp_buffer = strchr(temp_buffer, '\n') + 1;
      delete[] file_buffer;

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 14
    Last Post: 06-28-2006, 01:58 AM
  2. Replies: 8
    Last Post: 01-17-2006, 05:39 PM
  3. delete[] without new[]?
    By ChadJohnson in forum C++ Programming
    Replies: 6
    Last Post: 04-04-2005, 11:39 AM
  4. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  5. allocating memory screws up data being read in from file
    By Shadow12345 in forum C++ Programming
    Replies: 5
    Last Post: 12-06-2002, 03:23 PM