DevenD
DevenD

Reputation: 17

Error reading vector elements via a pointer which has the base address of the vector

My exe is accessing the vector assigned by dll. I am getting the base address via vector.data(). The problem is that the vector probably has more memory space allocated than required. So how do I read the memory that has the actual data allocated.

.dll code

Utf8String ICSClient::SampleMethod2(Utf8String* &p) 
    {
    vector<Utf8String> *temp = new vector<Utf8String>;
    temp->push_back("Liu");
    temp->push_back("Roy");
    temp->push_back("Shanu");

    p = temp->data(); // returns the pointer to the underlying array

    return success;
    }

.exe code // -----p is a pointer that is allocated the base address of the vector

while (p != NULL)
     {
      cout << *p << endl;
      p++;
     }

it appears that the p is not equal to null and then the exception is thrown when reading the memory that is not null.

Upvotes: 0

Views: 73

Answers (1)

Yksisarvinen
Yksisarvinen

Reputation: 22334

p won't get equal to NULL by itself. Can't tell exactly, because provided code lacks p pointer definition and ICSClient::SampleMethod2 call, but here you're reading array and then you go out of bounds of the array, which is Undefined Behaviour.

There is a memory leak as well, since you never free the memory allocated for vector and you lose the pointer to it with the end of function.

I see that you return some code here, which is probably a requirement, so you can't return vector. I'd suggest passing std::vector by reference, so you can use it in your function

Utf8String ICSClient::SampleMethod2(std::vector<Utf8String>& data) 
{
    data.clear();
    data.push_back("Liu");
    data.push_back("Roy");
    data.push_back("Shanu");

    return success;
}

EDIT: If passing std::vector by reference is not viable option, then you (and users of your dll) will have to deal with raw C arrays. Unfortunately, when passing array to a function, it gets downgraded to a pointer type, so passing size together with array is a necessity.

Utf8String ICSClient::SampleMethod2(Utf8String** data, size_t* size) 
{
    *size = 3;

    *data = new Utf8String[3];
    data[0] = "Liu";
    data[1] = "Roy";
    data[2] = "Shanu";

    return success;
}

Mind you, the user will have to manage memory (delete the array) by himself, which is not really an expected behaviour.

Upvotes: 1

Related Questions