3

I want to know how to properly delete the memory of std::vector & std:: map allocated in c++ code.

I am sharing my code here

 # include <vector>
 # include <stdio.h>
 # include <stdlib.h> //realloc
 # include <math.h>
 # include <map>
 # include <unordered_map>
 #include <emscripten/bind.h>

using namespace emscripten;


struct Edge{
    // Coordinates of two vertices
    float c[6];
    float normal[3];
    int i1,
    i2;
    Edge() {};
    Edge(const float * v1, const float * v2, const float * _normal, int _i1, int _i2) {
        i1 = _i1;
        i2 = _i2;
        memcpy( & normal[0], _normal, 3 * sizeof(float));
        // Compare coordinates lexicographically to select some fixed edge direction
        if (std::lexicographical_compare( & v1[0],  & v1[3],  & v2[0],  & v2[3])) {
            memcpy( & c[0], v1, 3 * sizeof(float));
            memcpy( & c[3], v2, 3 * sizeof(float));
        } else {
            memcpy( & c[0], v2, 3 * sizeof(float));
            memcpy( & c[3], v1, 3 * sizeof(float));
        }
    }

    // Comparison operator for storing edges in std::map
    bool operator < (const Edge & e)const{
        return std::lexicographical_compare( & c[0],  & c[6],  & e.c[0],  & e.c[6]);
    }

    bool operator ==(const Edge & edge)const{

       // return std::lexicographical_compare( & c[0],  & c[6],  & e.c[0],  & e.c[6]);

        if(c[0] == edge.c[0] && c[1] == edge.c[1] && c[2] == edge.c[2] &&
            c[3] == edge.c[3] && c[4] == edge.c[4] && c[5] == edge.c[5]
        )      
            return true;    
        else
            return false;
    }
};

std::vector < float > crossProduct(std::vector < float > vector1, std::vector < float > vector2) {
    std::vector < float > value;
    value.resize(3);
    value[0] = ((vector1[1] * vector2[2]) - (vector1[2] * vector2[1]));
    value[1] = ((vector1[2] * vector2[0]) - (vector1[0] * vector2[2]));
    value[2] = ((vector1[0] * vector2[1]) - (vector1[1] * vector2[0]));
    return value;
}

std::vector < float > subVector(float * vector1, float * vector2) {
    std::vector < float > value;
    value.resize(3);
    value[0] = ((vector1[0]) - (vector2[0]));
    value[1] = ((vector1[1]) - (vector2[1]));
    value[2] = ((vector1[2]) - (vector2[2]));
    return value;
}

std::vector < float > Normalize(std::vector < float > vector) {

    float length = sqrt(pow((vector[0]), 2) + pow((vector[1]), 2) + pow((vector[2]), 2));
    if (length > 0) {
        std::vector < float > value;
        value.resize(3);
        value[0] = vector[0] / length;
        value[1]= vector[1] / length;
        value[2] = vector[2] / length;
        return value;           
    }
    return vector;

}

std::vector<unsigned int> GetFeatureEdges(float fCreaseAngle, uintptr_t input, int nTriangles, bool bBoundaryEdgesOnly){

    std::vector < Edge > edges;
    const float* coords = reinterpret_cast<float*>(input);

    int nEdges = 3 * nTriangles;
    edges.resize(nEdges);
    # pragma omp parallel for
    for (int i = 0; i < nTriangles; i++) {
        int t = 3 * i;
        int y = 3 * 3 * i;
        float p[3][3];
        memcpy( & p[0],  & coords[y], sizeof(float) * 9);
        std::vector < float > normal = crossProduct(subVector(p[1], p[0]), subVector(p[2], p[0]));
        normal = Normalize(normal);
        for (int j = 0; j < 3; j++) {
            int k = (j + 1) % 3;
            edges[i * 3 + j] = Edge( & p[j][0],  & p[k][0],  & normal[0], t + j, t + k);
        }
    }

    float threshold = cos(fCreaseAngle * M_PI / 180);

    std::map < Edge, unsigned char > edge_info;

    for (int i = 0; i < nEdges; i++) {
        std::map < Edge,
        unsigned char > ::iterator it = edge_info.find(edges[i]);
        if (it == edge_info.end())
            edge_info[edges[i]] = 1; // Add edge and mark it as unpaired
        else if (it->second == 1) {
            if (bBoundaryEdgesOnly) {
                edge_info.erase(it);
            } else {
                float dot = edges[i].normal[0] * it->first.normal[0] + edges[i].normal[1] * it->first.normal[1] + edges[i].normal[2] * it->first.normal[2];
                if (dot > 1.0f)
                    dot = 1.0f;
                else if (dot < -1.0f)
                    dot = -1.0f;
                if (dot > threshold) {
                    it->second = 2; // Mark edge as as unpaired, because faces are within crease angle
                    edge_info.erase(it);
                } else
                    it->second = 0; // Mark edge as forced feature edge (this is for case when edge is shared by 3+ faces)
            }
        }
    }

   std::vector<unsigned int> res;
    res.resize(edge_info.size() * 2);
    size_t count=0;
    for (std::map<Edge, unsigned char>::const_iterator it = edge_info.begin(); it != edge_info.end(); it++)
    {       
        res[count++]=it->first.i1;
        res[count++]=it->first.i2;
    }

    edges.clear();
    edge_info.clear();

    return res;
}




EMSCRIPTEN_BINDINGS(VCT_wrappers) {
    register_vector<unsigned int>("VectorUInt");
    function("GetFeatureEdges", &GetFeatureEdges, allow_raw_pointers());
}

emcc compilation is

emcc --bind -o featureEdge.js featureEdge.cpp -O3 --memory-init-file 0 -s ALLOW_MEMORY_GROWTH=1 -v 

and my js function code is

function _arrayToHeap(typedArray) {
        var numBytes = typedArray.length * typedArray.BYTES_PER_ELEMENT;
        var ptr = Module._malloc(numBytes);
        var heapBytes = new Uint8Array(Module.HEAPU8.buffer, ptr, numBytes);
        heapBytes.set(new Uint8Array(typedArray.buffer));
        return heapBytes;
    }
function _freeArray(heapBytes) {
        Module._free(heapBytes.byteOffset);
    }
function GetFeatureEdges_asm(nodeName, fCreaseAngle, vertices, nTriangles, bBoundaryEdgesOnly) {

        //var vertices = new Float32Array([0, 0, 0, 10, 0, 0, 5, 10, 0,
        //          10, 0, 0, 10, 10, 0, 5, 10, 0,
        //          0, 0, 0, 5, 10, 0, 0, 10, 0]);

        //nTriangles = vertices.length / 3 / 3;
        // console.log(nTriangles);

        //var startTime = Date.now();

        var dataHeap1 = _arrayToHeap(vertices);        
        var obj = Module.GetFeatureEdges(35.0, dataHeap1.byteOffset, nTriangles, 0);


        var count = obj.size();

        var indexData = new Uint32Array(count);
        for (var i = 0; i < count; i++)
            indexData[i] = obj.get(i);     


        obj.resize(0, 0);
        obj.delete();


        _freeArray(dataHeap1);

        //var diffTime = Date.now() - startTime;
        //time = time + diffTime

        return indexData;
    }

Here "vertices" is very big array of float values.

If i use this

struct Edge *edges = new struct Edge[nEdges];
delete[] edges;
edges = NULL;

instead of

std::vector < Edge > edges;
edges.resize(nEdges);

there is not memory leak in chrome browser and my emscripten version is 1.37.21.

can any one help me in this?

1
  • I have the same problem! Commented Oct 20, 2020 at 1:30

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.