title: C++ OpenGL glTexImage2D Access Violation
body: <p>I'm writing an application using OpenGL (freeglut and glew).</p>
  
  <p>I also wanted textures so I did some research on the Bitmap file format and wrote a struct for the main header and another for the DIB header (info header).</p>
  
  <p>Then I started writing the loader. It automatically binds the texture to OpenGL. Here is the function:</p>
  
  <pre><code>static unsigned int ReadInteger(FILE *fp)
  {
      int a, b, c, d;
  
      // Integer is 4 bytes long.
      a = getc(fp);  
      b = getc(fp);  
      c = getc(fp);  
      d = getc(fp);
  
      // Convert the 4 bytes to an integer.
      return ((unsigned int) a) + (((unsigned int) b) &lt;&lt; 8) +
             (((unsigned int) c) &lt;&lt; 16) + (((unsigned int) d) &lt;&lt; 24);
  }
  
  static unsigned int ReadShort(FILE *fp)
  {
      int a, b;
  
      // Short is 2 bytes long.
      a = getc(fp);  
      b = getc(fp);
  
      // Convert the 2 bytes to a short (int16).
      return ((unsigned int) a) + (((unsigned int) b) &lt;&lt; 8);
  }
  
      GLuint LoadBMP(const char* filename)
  {
      FILE* file;
  
      // Check if a file name was provided.
      if (!filename)
          return 0;
  
      // Try to open file.
      fopen_s(&amp;file, filename, "rb");
  
      // Return if the file could not be open.
      if (!file)
      {
          cout &lt;&lt; "Warning: Could not find texture '" &lt;&lt; filename &lt;&lt; "'." &lt;&lt; endl;
          return 0;
      }
  
      // Read signature.
      unsigned char signature[2];
      fread(&amp;signature, 2, 1, file);
  
      // Use signature to identify a valid bitmap.
      if (signature[0] != BMPSignature[0] || signature[1] != BMPSignature[1])
      {
          fclose(file);
          return 0;
      }
  
      // Read width and height.
      unsigned long width, height;
      fseek(file, 16, SEEK_CUR); // After the signature we have 16bytes until the width.
      width = ReadInteger(file);
      height = ReadInteger(file);
  
      // Calculate data size (we'll only support 24bpp).
      unsigned long dataSize;
      dataSize = width * height * 3;
  
      // Make sure planes is 1.
      if (ReadShort(file) != 1)
      {
          cout &lt;&lt; "Error: Could not load texture '" &lt;&lt; filename &lt;&lt; "' (planes is not 1)." &lt;&lt; endl;
          return 0;
      }
  
      // Make sure bpp is 24.
      if (ReadShort(file) != 24)
      {
          cout &lt;&lt; "Error: Could not load texture '" &lt;&lt; filename &lt;&lt; "' (bits per pixel is not 24)." &lt;&lt; endl;
          return 0;
      }
  
      // Move pointer to beggining of data. (after the bpp we have 24 bytes until the data)
      fseek(file, 24, SEEK_CUR);
  
      // Allocate memory and read the image data.
      unsigned char* data = new unsigned char[dataSize];
  
      if (!data)
      {
          fclose(file);
          cout &lt;&lt; "Warning: Could not allocate memory to store data of '" &lt;&lt; filename &lt;&lt; "'." &lt;&lt; endl;
          return 0;
      }
  
      fread(data, dataSize, 1, file);
  
      if (data == NULL)
      {
          fclose(file);
          cout &lt;&lt; "Warning: Could no load data from '" &lt;&lt; filename &lt;&lt; "'." &lt;&lt; endl;
          return 0;
      }
  
      // Close the file.
      fclose(file);
  
      // Create the texture.
      GLuint texture;
      glGenTextures(1, &amp;texture);
      glBindTexture(GL_TEXTURE_2D, texture);
  
      glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); //NEAREST);
      glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 
  
      gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, width, height, GL_BGR_EXT, GL_UNSIGNED_BYTE, data);
  
      return texture;
  }
  </code></pre>
  
  <p>I know that the bitmap's data is correctly read because I outputted it's data to the console and compared with the image opened in paint.</p>
  
  <p>The problem here is this line:</p>
  
  <pre><code>glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, dibheader.width,
      dibheader.height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
  </code></pre>
  
  <p>Most of the times I run the application this line crashes with the error:</p>
  
  <blockquote>
    <p>Unhandled exception at 0x008ffee9 in GunsGL.exe: 0xC0000005: Access violation reading location 0x00af7002.</p>
  </blockquote>
  
  <p>This is the Disassembly of where the error occurs:</p>
  
  <pre><code>movzx       ebx,byte ptr [esi+2]
  </code></pre>
  
  <p>It's not an error with my loader, because I've downloaded other loaders.
  A downloaded loader that I used was <a href="http://nehe.gamedev.net/tutorial/collision_detection/17005/" rel="nofollow">this one</a> from NeHe.</p>
  
  <p>EDIT: (CODE UPDATED ABOVE)</p>
  
  <p>I rewrote the loader, but I still get the crash on the same line. Instead of that crash, sometimes I get a crash on mlock.c (same error message is I recall correctly):</p>
  
  <pre><code>void __cdecl _lock (
          int locknum
          )
  {
  
          /*
           * Create/open the lock, if necessary
           */
          if ( _locktable[locknum].lock == NULL ) {
  
              if ( !_mtinitlocknum(locknum) )
                  _amsg_exit( _RT_LOCK );
          }
  
          /*
           * Enter the critical section.
           */
  
          EnterCriticalSection( _locktable[locknum].lock );
  }
  </code></pre>
  
  <p>On the line:</p>
  
  <pre><code>EnterCriticalSection( _locktable[locknum].lock );
  </code></pre>
  
  <p>Also, here is a screen shot of one of those times the applications doesn't crash (the texture is obviously not right):
  <a href="http://i.stack.imgur.com/4Mtso.jpg" rel="nofollow">http://i.stack.imgur.com/4Mtso.jpg</a></p>
  
  <p><strong>Edit2:</strong></p>
  
  <p>Updated code with the new working one.
  (The reply marked as an answer does not contain all that was needed for this to work, but it was vital)</p>