Search code examples
cdirectoryrealloc

Realloc() returning NULL when memory is available - C


  • OS:Windows Vista(x86)
  • Compiler: Code::Blocks

I am currently writing a program that opens a specified directory and reads the contents of it. Rather than using printf() to display the file names immediately after they are found. I hold them in memory and display them later. I use the following if statement to trigger memory reallocation. I have also included the declarations of relevant variables.

//Represents what the new index will be after the current file name is added
//to 'stack.ptr'
#define NEW_INDEX (stack.index+(strlen(ptr_dirent->d_name)))

//Contains the pointer that points to the directory's contents 'stack.ptr',
//the size of 'stack.ptr' which is 'stack.size', and the current index
//'stack.index'
struct stack
{
  int index;
  char *ptr;
  int size;
};struct stack stack;

//Sets the index to 0 and allocates 256 bytes of memory for 'stack.ptr'
stack.index = 0; stack.size = 256;
stack.ptr = malloc(sizeof(char)*stack.size);

if(NEW_INDEX > stack.size)
{
  char *temp; stack.size *= 2;
  temp = realloc(stack.ptr, sizeof(char)*stack.size);
  if (temp == NULL)
  {
    printf("ERROR: %i Bytes of memory could not be allocated.\n", stack.size);
    free(stack.ptr); closedir(dirp); return '\000';
  }
  else {stack.ptr = temp;}
}

The program works perfectly until I set the initial value of 'stack.size'(which is the array size) to 2 rather than 256 (so that the program HAS to reallocate memory). My program crashed because realloc() returned NULL but I had plenty of memory available. I know that realloc() did work a couple of times because 'stack.size' was 16 when it crashed ('stack.size' is doubled every time memory is reallocated). I tried setting 'stack.size' to a couple of different values and I found that setting 'stack.size' to 1 or 2 causes a crash and it always happens when 'stack.size' reaches 16. Can anyone explain this to me? I am worried that even if I set 'stack.size' to 256 my program may crash if a directory is large enough to trigger memory reallocation. Also in an unrelated note, I read that openddir("."); will open the current directory and I have found that it does but for some reason not all of the files in the current directory are in 'stack.ptr' and a . and .. are displayed when I output the contents of 'stack.ptr' to stdout.


Solution

  • You didn't show us the line that contains the bug. It probably looks like:

    strcpy(stack.ptr+stack.index, ptr_dirent->d_Name);
    

    The problem here is that strcpy() copies strlen() + 1 bytes. You are writing the terminating NUL char beyond the end of your allocated array.