-2

The idea is to load a Wavefront OBJ file and render it using DirectX 11.0. So far everything works, except for the actual loading of the geometry.

I allocate an array of pointers to floats to contain my vertex positions, texture coordinates and normals:

pfVertices_ = new float[nTotalVertices_ * 3];
pfNormals_ = new float[nTotalVertices_ * 3];
pfTexcoords_ = new float[nTotalVertices_ * 2];

And I release them, of course:

delete[] pfVertices_;
delete[] pfNormals_;
delete[] pfTexcoords_;

When I try to load a model containing roughly 9200 vertices, I get an access violation. I understand what the problem is, I just don't really know how to solve it. I've tried malloc() and free(), but AFAIK you can't cast a void* into a float* without asking for trouble, and it still gives me the access violation.

So, my question: Is there a safe way to allocate large arrays dynamically, or should I just put up with new's shortcomings?

EDIT: So yeah, I knew std::vector existed since the very beginning. I shied away from it because of some bad experience, and because I fear for its performance when the graphics engine becomes heavy on the GPU.

Anyway, I converted everything to std::vector, and I don't get the access violation again. BUT my geometry is invisible. I (kind of) tried if it was a problem with camera direction/position, and it wasn't. I also checked the Graphics Debugger, without any visible problems. I've had this invisible geometry problem before, but then it had to do with the rasterizer state, which can't be the case here. Does anyone have some advice about where to look for the problem?

  • 1
    You are allocating and deleting the memory correctly, your issue is elsewhere. If the allocation was the problem you'd get a `std::bad_alloc`, an access violation is a different problem. – Cory Kramer Jun 16 '15 at 18:40
  • 1
    There's nothing obviously wrong here. This should work. I'm afraid your problem's probably elsewhere. You sound like you're on Windows; do you have access to a memory bounds checking tool like Linux's valgrind? – David Given Jun 16 '15 at 18:41
  • An access violation is no 'std::bad_alloc' exception thrown by 'new', hence you have no allocation problem. –  Jun 16 '15 at 18:42
  • Incidentally, as you're in a hurry, some quick-and-dirty debugging tips: allocate with `new float[size*2] + (size/2)`, and then free with `delete[] (ptr - size/2)`. That'll give you `size/2` indices of buffer before and after your array. If your program stops crashing, you have a buffer overrun problem. – David Given Jun 16 '15 at 18:47
  • Also, try commenting out your `delete[]` lines completely. Your program will leak memory like there's no tomorrow, but if it stops crashing, you have a using-pointer-after-freeing problem. – David Given Jun 16 '15 at 18:48

1 Answers1

2

Yes! You should definitely use std::vector instead of new[]! It will do all the memory management for you, and you can have range checked access with either std::vector::at or your platforms debugging facilities.

This will by itself of course not prevent access violations, but it is able to tell you with great detail (or at least more precise than what you have with new[]) where they occur, like e.g. what index you tried to access and how big the array actually is.

With those information, finding the underlying issue is usually a whole lot easier than from just a pretty useless "Segmentation fault".

Using std::vector will also make it harder for you to make some (sadly still common) mistakes like "use after free" bugs.

Community
  • 1
  • 1
Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
  • Regardless, their allocation isn't the cause of the problem, so switching to `std::vector` won't solve their issue. – Cory Kramer Jun 16 '15 at 18:41
  • @CoryKramer But it will give them a better idea where the issue lies because you trade nice debugging behavior for dumb UB crashes. – Baum mit Augen Jun 16 '15 at 18:43
  • 1
    No! Just write correct code (I never use std::vector::at) –  Jun 16 '15 at 18:44
  • 4
    @DieterLücking I don't either, but I do use the debugging facilities my platform provides to tell me (in some cases at least) when I screwed up. "Just write correct code" is about as useful as the doctor saying "Just don't get sick". – Baum mit Augen Jun 16 '15 at 18:47
  • std::vector::at is no debugging facility. –  Jun 16 '15 at 19:40
  • @DieterLücking I never claimed that it is. Please read my answer more carefully. – Baum mit Augen Jun 16 '15 at 19:42