From 520162f36a0ff188b5b3db89d095c0660ad562f2 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Thu, 9 Oct 2014 19:02:29 +0200 Subject: [PATCH] Use safe way to get at a vector's data pointer &std::vector[0] is not guaranteed to not throw if the vector is empty. Better safe than sorry. --- binding-mruby/mrb-ext/rwmem.cpp | 2 +- src/global-ibo.h | 2 +- src/quadarray.h | 4 ++-- src/tileatlasvx.cpp | 2 +- src/tilemap.cpp | 6 +++--- src/tilemapvx.cpp | 4 ++-- src/util.h | 13 +++++++++++++ src/windowvx.cpp | 6 +++--- 8 files changed, 26 insertions(+), 13 deletions(-) diff --git a/binding-mruby/mrb-ext/rwmem.cpp b/binding-mruby/mrb-ext/rwmem.cpp index 7245ffd..1c83061 100644 --- a/binding-mruby/mrb-ext/rwmem.cpp +++ b/binding-mruby/mrb-ext/rwmem.cpp @@ -101,7 +101,7 @@ int RWMemGetData(SDL_RWops *ops, void *buffer) ByteVec *v = getRWPrivate(ops); if (buffer) - memcpy(buffer, &(*v)[0], v->size()); + memcpy(buffer, dataPtr(*v), v->size()); return v->size(); } diff --git a/src/global-ibo.h b/src/global-ibo.h index 77ff555..c8beaf3 100644 --- a/src/global-ibo.h +++ b/src/global-ibo.h @@ -67,7 +67,7 @@ struct GlobalIBO } IBO::bind(ibo); - IBO::uploadData(buffer.size() * sizeof(index_t), &buffer[0]); + IBO::uploadData(buffer.size() * sizeof(index_t), dataPtr(buffer)); IBO::unbind(); } }; diff --git a/src/quadarray.h b/src/quadarray.h index f4037ed..8751739 100644 --- a/src/quadarray.h +++ b/src/quadarray.h @@ -86,7 +86,7 @@ struct QuadArray { /* New data exceeds already allocated size. * Reallocate VBO. */ - VBO::uploadData(size, &vertices[0], GL_DYNAMIC_DRAW); + VBO::uploadData(size, dataPtr(vertices), GL_DYNAMIC_DRAW); vboSize = size; shState->ensureQuadIBO(quadCount); @@ -94,7 +94,7 @@ struct QuadArray else { /* New data fits in allocated size */ - VBO::uploadSubData(0, size, &vertices[0]); + VBO::uploadSubData(0, size, dataPtr(vertices)); } VBO::unbind(); diff --git a/src/tileatlasvx.cpp b/src/tileatlasvx.cpp index 7a5f48c..5af8060 100644 --- a/src/tileatlasvx.cpp +++ b/src/tileatlasvx.cpp @@ -265,7 +265,7 @@ createShadowSet() /* Fill rects with half opacity black */ uint32_t color = (0x80808080 & am); - SDL_FillRects(surf, &rects[0], rects.size(), color); + SDL_FillRects(surf, dataPtr(rects), rects.size(), color); return surf; } diff --git a/src/tilemap.cpp b/src/tilemap.cpp index 9878275..ac50c70 100644 --- a/src/tilemap.cpp +++ b/src/tilemap.cpp @@ -766,7 +766,7 @@ struct TilemapPrivate VBO::bind(tiles.vbo); VBO::allocEmpty(quadDataSize(quadCount)); - VBO::uploadSubData(0, quadDataSize(groundQuadCount), &groundVert[0]); + VBO::uploadSubData(0, quadDataSize(groundQuadCount), dataPtr(groundVert)); for (size_t i = 0; i < zlayersMax; ++i) { @@ -774,7 +774,7 @@ struct TilemapPrivate continue; VBO::uploadSubData(quadDataSize(zlayerBases[i]), - quadDataSize(zlayerSize(i)), &zlayerVert[i][0]); + quadDataSize(zlayerSize(i)), dataPtr(zlayerVert[i])); } VBO::unbind(); @@ -855,7 +855,7 @@ struct TilemapPrivate return; VBO::bind(flash.vbo); - VBO::uploadData(sizeof(CVertex) * vertices.size(), &vertices[0]); + VBO::uploadData(sizeof(CVertex) * vertices.size(), dataPtr(vertices)); VBO::unbind(); /* Ensure global IBO size */ diff --git a/src/tilemapvx.cpp b/src/tilemapvx.cpp index bbd925d..d45e82d 100644 --- a/src/tilemapvx.cpp +++ b/src/tilemapvx.cpp @@ -236,8 +236,8 @@ struct TilemapVXPrivate : public ViewportElement, TileAtlasVX::Reader allocQuads = totalQuads; } - VBO::uploadSubData(0, quadBytes(groundQuads), &groundVert[0]); - VBO::uploadSubData(quadBytes(groundQuads), quadBytes(aboveQuads), &aboveVert[0]); + VBO::uploadSubData(0, quadBytes(groundQuads), dataPtr(groundVert)); + VBO::uploadSubData(quadBytes(groundQuads), quadBytes(aboveQuads), dataPtr(aboveVert)); VBO::unbind(); diff --git a/src/util.h b/src/util.h index 8009a26..2a48ef4 100644 --- a/src/util.h +++ b/src/util.h @@ -25,6 +25,7 @@ #include #include #include +#include static inline int wrapRange(int value, int min, int max) @@ -101,6 +102,18 @@ inline bool contains(const C &c, const V &v) return std::find(c.begin(), c.end(), v) != c.end(); } +template +inline const C *dataPtr(const std::vector &v) +{ + return v.empty() ? (C*)0 : &v[0]; +} + +template +inline C *dataPtr(std::vector &v) +{ + return v.empty() ? (C*)0 : &v[0]; +} + #define ARRAY_SIZE(obj) (sizeof(obj) / sizeof((obj)[0])) #define elementsN(obj) const size_t obj##N = ARRAY_SIZE(obj) diff --git a/src/windowvx.cpp b/src/windowvx.cpp index cc6d193..0b01a6e 100644 --- a/src/windowvx.cpp +++ b/src/windowvx.cpp @@ -374,7 +374,7 @@ struct WindowVXPrivate base.vert.resize(count); - Vertex *vert = &base.vert.vertices[0]; + Vertex *vert = dataPtr(base.vert.vertices); size_t i = 0; /* Stretched background */ @@ -518,7 +518,7 @@ struct WindowVXPrivate }; size_t i = 0; - Vertex *vert = &ctrlVert.vertices[0]; + Vertex *vert = dataPtr(ctrlVert.vertices); if (!nullOrDisposed(contents) && arrowsVisible) { @@ -600,7 +600,7 @@ struct WindowVXPrivate quads += 1; cursorVert.resize(quads); - Vertex *vert = &cursorVert.vertices[0]; + Vertex *vert = dataPtr(cursorVert.vertices); size_t i = 0; i += Quad::setTexPosRect(&vert[i*4], src.corners.tl, cornerPos.tl);