As Hodgeman has already pointed out and as your code clearly shows, you are allocating way to less memory. sizeof(vertexData) returns the size of the datatype of vertexData, which is GLfloat, which is 4 byte. You need sizeof(float)*numVertices*numElementsPerVertex in order allocate a correctly sized buffer.
Though I'm no expert on the details, the reason why having less bytes not crash is that behaviour is somewhat undefined if violating memory boundaries. For example, a fellow colleque of mine had a fixed-size texture cache with an array of size 23, but she did in fact store 25 textures without any problem whatsoever. I at some point deleted a dynamic array without  and didn't get a crash until like a week later in some unrelated code piece. I also once deleted memory twice and got some strange DirectX11-related error from the GPU that didn't have anything to do with the issue itself. The thing is, when you are writing over the boundaries of like an array, you are writing to some random region of memory, where eigther nothing can be allocated yet, or you could overwrite something from another array, etc... if you are lucky, the debugger catches on to it, if not, such random things as in your case happen. Bottom line: Memory is stupid, always triple-check when dealing with raw memory management.