EnabrenTane
EnabrenTane

Reputation: 7466

segfault when using sizeof(vector[0]) * vector->size()

Given the working code snippet

    glBufferData(GL_ARRAY_BUFFER, vertices->size() * sizeof(glm::vec3), &vertices->front(), GL_STATIC_DRAW); // Set the size and data of our VBO and set it to STATIC_DRAW
    glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0); // Set up our vertex attributes pointer


    glGenBuffers(1,&indexBufferId);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,indexBufferId);
    // We have to use &triangles.front() otherwise we get vector house keeping garbage
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, triangles->size() * sizeof(unsigned), &triangles->front(), GL_STATIC_DRAW); // Set the size and data of our VBO and set it to STATIC_DRAW
    glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0); // Set up our vertex attributes pointer

basically I am sending data to OpenGL and naturally I have to tell it where to copy from, and how much to copy. After changing types on my vectors a few times I decided I didn't want to keep updating every type reference and tried the following line.

 glBufferData(GL_ELEMENT_ARRAY_BUFFER, triangles->size() * sizeof(triangles[0]), &triangles->front(), GL_STATIC_DRAW); // Set the size and data of our VBO and set it to STATIC_DRAW

using sizeof(triangles[0]) instead of sizeof(unsigned). Figuring hey my vector is typed so it should be able to figure the type of an element at compile time so I don't have to tell it each refactor.

However this is not the case. This single change causes a segfault when done to either line with their respective vector.

Another point of confusion (arose when trying to compact my code) is using

  glBufferData(GL_ELEMENT_ARRAY_BUFFER, triangles->size() * sizeof(unsigned), &triangles[0], GL_STATIC_DRAW); 

replacing &triangles.front() with &triangles[0] causes the same segfault. I was of the understanding that these two statements should be equal.

Where is my misunderstanding? I thought the statements which are segfaulting were equivalent to the working ones.

Upvotes: 1

Views: 474

Answers (2)

luiscubal
luiscubal

Reputation: 25121

Since you are using vector->size(), that means vector must be a pointer(unless you are using some operator overloading magic).

Although vector does have operator [], vector*[] will not behave as you expect it to.

#include <vector>
#include <iostream>

using std::vector;
using std::cout;
using std::endl;

int main() {
    vector<int>* x = new vector<int>();
    x->push_back(3);
    x->push_back(4);

    cout << sizeof(vector<int>*) << endl;
    cout << sizeof(x) << endl;
    cout << sizeof(vector<int>) << endl;
    cout << sizeof(*x) << endl;
    cout << sizeof(x[0]) << endl;
    cout << sizeof(int) << endl;
    cout << sizeof((*x)[0]) << endl;

    return 0;
}

On my machine, that program outputs this:

8
8
24
24
24
4
4

In other words, sizeof(vector[0]) will give you the size of vector, not the size of each vector element. And since the size calculation is wrong, segmentation fault issues are expected.

Upvotes: 3

K-ballo
K-ballo

Reputation: 81349

You don't show the declaration of triangles, but from how you use it it seems to be std::vector<unsigned>* (note the pointer). With that in mind, it should be:

sizeof( (*triangles)[0] )

and

&(*triangles)[0]

Upvotes: 1

Related Questions