problem with passing custom array to function (c++) - c++

I have an array of type T which I pass as a pointer parameter to a function.
The problem is that I can't write new data to this array properly, without getting memory violation at the second try.
In this code I read integers from a text file and pass them to the function (part of template class of type T), in order to append them to the array.
After I finish to append the integers, I want to use the same array back in the Main.
Does someone know what's wrong with the code?
Thanks, Max
template<class T> int CFile<T>::read(T **apBuf, int aNum)
{
int readCounter = 0;
*apBuf = (T*)malloc(sizeof(T)*aNum);
for (int i = 0; i<aNum; i++)
{
T var = read();
if (var == NULL)
{
if (isEof)
{
return readCounter;
}
else
{
perror ("Error Reading File - Insufficient var type");
return -1;
}
}
else
{
*apBuf[i] = var;
readCounter++;
}
}
return readCounter;
}

*apBuf[i] = var;
This is parsed as if it was written:
*(apBuf[i]) = var;
This is obviously not what you want; apBuf is a pointer to a pointer to an array; you are treating it as a pointer to an array and you are dereferencing the ith element of it. What you really mean is:
(*apBuf)[i] = var;
*apBuf gives you "the object pointed to by apBuf," which is the array; then you obtain the ith element of the array.
That said, this is rather unusual: why not accumulate the data into a std::vector<T> and return that from the function? Then you don't have to worry about the explicit dynamic memory management. (Also, is T always a pointer type? If not, then var == NULL makes no sense.)

Well, you used malloc to allocate the array, and then tried to assign to it. This is undefined behaviour, because you have to construct the objects.
Oh, and you should really, really consider using self-owning resource classes, because malloc and this style of programming in general is hideously unsafe. What if T's copy constructor throws an exception? Memory leak. Just for example.

One issue you have is your using malloc instead of new. If T is a class the constructor won't be called.

Related

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.
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.

Why is Eigen matrix to C array conversion giving garbage values for the first two indices?

I have an Eigen matrix to be converted to a C array. I can replicate the issue with the following example.
#include <iostream>
#include <Eigen/Core>
int *test()
{
Eigen::MatrixXi arr = Eigen::MatrixXi::Ones(6,1);
// just to check
arr(4)=3;
arr(5)=19;
return arr.data();
}
int main()
{
int *c_arr;
c_arr = test();
for (int i=0; i<6;++i)
{
std::cout << c_arr[i] << std::endl;
}
return 0;
}
Output:
0
0
1
1
3
19
Now if I print the converted C array values from within the test function the values are correct. However if I print the values from main (as shown above) the first two indices are always garbage. So I am wondering what is happening in the function call? I have tried this with different Eigen matrices (types, sizes) and I get the same result.
I'll start by saying I'm not 100% familiar with the Eigen library (just downloaded it to look at it out of curiosity) and it's documentation is a bit lacking but your problem is a fundamental C problem that can be remedied a few ways.
First we'll start by explaining what's happening in your code to give garbage values:
int *test()
{
/* create an auto scoped variable on the stack;
this variable is only "visible" to this function
and any references to it or it's underlying data
outside the scope of this function will result
in "undefined behaviour" */
Eigen::MatrixXi arr = Eigen::MatrixXi::Ones(6,1);
arr(4)=3;
arr(5)=19;
/* arr.data() is defined as returning a pointer to the scalar underlying type (or
a C-style array in other words). Regardless of the type being returned, it is pointer based
and you are returning a pointer to a location in memory, not the actual data being held in
the memory. */
return arr.data();
} /* the variable arr is destroyed here since we left function scope and the return value (the pointer location)
is put in the return register and "program flow" is returned back to the main function where the pointer being
returned now points to "invalid" memory */
int main()
{
int *c_arr; // create a pointer type that can reference int types
c_arr = test(); // point it to the result of the test function (see notes above)
/* c_arr now points to a memory location returned from test, but since the
arr variable no longer exists here, when you go through and print the values pointed
to at those memory locations you will get what is at those locations and could be "anything"
except a valid reference to the original arr variable and it's underlying data. */
for (int i=0; i<6;++i)
{
std::cout << c_arr[i] << std::endl;
}
return 0;
}
So that's the why, as for how to fix it there are a couple of ways to go about your problem; one is to pass the return array in as a variable in to your test function (e.g. void test(int*& val)), you could then choose to allocate new memory to the variable in the test function, or assume the user has already done so, and must also assume the user will clean up after themselves and call delete[] (not just delete since you're operating on arrays of data).
But this has many caveats of needing to know how much space to allocate and being sure to deallocate when done. I'm not sure why you specifically need a C-style array but since you're using C++, it might be more prudent if you use some of the STL and container functions available to you to help you out, example:
#include <iostream>
#include <vector>
#include <Eigen/Core>
std::vector<int> test()
{
Eigen::MatrixXi arr = Eigen::MatrixXi::Ones(6,1);
arr(4)=3;
arr(5)=19;
// we need the size so we know how big of a container to allocate
std::size_t sz = arr.innerSize() * arr.outerSize();
std::vector<int> ret(sz);
// get a temporary C array pointer so we can reference the data
int* tmp = arr.data();
// copy from tmp[0] to tmp[sz] and insert the data into the first element of ret
std::copy(tmp, tmp+sz, ret.begin());
// return the (copied) data
return ret;
}
int main()
{
std::vector<int> c_arr = test();
// c_arr now points to valid data it holds and can be iterated on
for (std::size_t i = 0; i < c_arr.size(); ++i) {
std::cout << c_arr[i] << std::endl;
}
// if you need a C-style array from here, you can easily copy the data
// from the vector to your C-array
return 0;
}
I looked into using the cast() function of the class, but could not quite figure out the syntax to make it less painful than just copying it the above way since it looks like you'd have to call the cast function to a differnt Eigen type and then cast again from there, but know there is a cast function and other methods to get the underlying data of the MatrixX classes if you need access to it.
I hope that can help.

NULL as a parameter

I am a bit confused when you pass NULL as a parameter
for example
int* array_create( int* array,size)
{
array = new int[size];
return array;
}
int main()
{
int* array = array_create(NULL,10);//can we pass NULL in this case?
delete[] array;
return 0;
}
I know the example is kinda stupid, but I am wondering if we can pass NULL as the parameter when the function assigns some heap memory to a pointer and returns it?
When you call your function like this...
int* array = array_create(NULL,10);//can we pass NULL in this case?
...you are getting behaviour like:
int* array_create(...)
{
int* array = NULL;
size_t size = 10; // using size_t as you'd missed any type
array = new int[size];
return array;
}
Ultimately, array is initialised to NULL then shortly afterwards overwritten with the value returned by new, so the initialisation serves no purpose.
For this code, there was simply no point passing an array argument... you could have created a local variable directly:
int* array_create(size_t n)
{
int* array = new int[size];
return array;
}
...or even...
int* array_create(size_t n)
{
return new int[size];
}
I am wondering if we can pass NULL as the parameter when the function assigns some heap memory to a pointer and returns it?
This requirement doesn't make much sense, as the two things are unrelated. You can pass whatever you like, and return whatever you like.
More commonly, a function might do something like:
void dump_bytes(std::ostream& os, unsigned char* p, size_t n)
{
if (p)
for (size_t i = 0; i < n; ++i)
os << static_cast<int>(p[i]) << ' ';
}
In dump_bytes, specifying a p value of NULL would fail the if (p) condition, ensuring the function didn't invoke undefined behaviour by dereferencing via a NULL pointer, even if n was not 0.
Just summarizing from the comments:
Yes, it is completely valid, but in Your example it is completely useless (you know that)
Some examples of this in real code:
In OpenGL you can tell the API if the data you want is coming from is from a buffer:
glBufferData(..., nullptr);
But wait! That's not null, that's nullptr?
Well in a c++11 compiler nullptr is a better option. Because NULL often usually resolves to 0, a version of the method that takes an int instead of a pointer the compiler will choose the int.
Here's some more data on that:
http://en.cppreference.com/w/cpp/language/nullptr
Also, if you want to edit an array, you should pass a pointer to a pointer.

How to avoid dynamic allocation of memory C++

[edit] Outside of this get method (see below), i'd like to have a pointer double * result; and then call the get method, i.e.
// Pull results out
int story = 3;
double * data;
int len;
m_Scene->GetSectionStoryGrid_m(story, data, len);
with that said, I want to a get method that simply sets the result (*&data) by reference, and does not dynamically allocate memory.
The results I am looking for already exist in memory, but they are within C-structs and are not in one continuous block of memory. Fyi, &len is just the length of the array. I want one big array that holds all of the results.
Since the actual results that I am looking for are stored within the native C-struct pointer story_ptr->int_hv[i].ab.center.x;. How would I avoid dynamically allocating memory like I am doing above? I’d like to point the data* to the results, but I just don’t know how to do it. It’s probably something simple I am overlooking… The code is below.
Is this even possible? From what I've read, it is not, but as my username implies, I'm not a software developer. Thanks to all who have replied so far by the way!
Here is a snippet of code:
void GetSectionStoryGrid_m( int story_number, double *&data, int &len )
{
std::stringstream LogMessage;
if (!ValidateStoryNumber(story_number))
{
data = NULL;
len = -1;
}
else
{
// Check to see if we already retrieved this result
if ( m_dStoryNum_To_GridMap_m.find(story_number) == m_dStoryNum_To_GridMap_m.end() )
{
data = new double[GetSectionNumInternalHazardVolumes()*3];
len = GetSectionNumInternalHazardVolumes()*3;
Story * story_ptr = m_StoriesInSection.at(story_number-1);
int counter = 0; // counts the current int hv number we are on
for ( int i = 0; i < GetSectionNumInternalHazardVolumes() && story_ptr->int_hv != NULL; i++ )
{
data[0 + counter] = story_ptr->int_hv[i].ab.center.x;
data[1 + counter] = story_ptr->int_hv[i].ab.center.y;
data[2 + counter] = story_ptr->int_hv[i].ab.center.z;
m_dStoryNum_To_GridMap_m.insert( std::pair<int, double*>(story_number,data));
counter += 3;
}
}
else
{
data = m_dStoryNum_To_GridMap_m.find(story_number)->second;
len = GetSectionNumInternalHazardVolumes()*3;
}
}
}
Consider returning a custom accessor class instead of the "double *&data". Depending on your needs that class would look something like this:
class StoryGrid {
public:
StoryGrid(int story_index):m_storyIndex(story_index) {
m_storyPtr = m_StoriesInSection.at(story_index-1);
}
inline int length() { return GetSectionNumInternalHazardVolumes()*3; }
double &operator[](int index) {
int i = index / 3;
int axis = index % 3;
switch(axis){
case 0: return m_storyPtr->int_hv[i].ab.center.x;
case 1: return m_storyPtr->int_hv[i].ab.center.y;
case 2: return m_storyPtr->int_hv[i].ab.center.z;
}
}
};
Sorry for any syntax problems, but you get the idea. Return a reference to this and record this in your map. If done correctly the map with then manage all of the dynamic allocation required.
So you want the allocated array to go "down" in the call stack. You can only achieve this allocating it in the heap, using dynamic allocation. Or creating a static variable, since static variables' lifecycle are not controlled by the call stack.
void GetSectionStoryGrid_m( int story_number, double *&data, int &len )
{
static g_data[DATA_SIZE];
data = g_data;
// continues ...
If you want to "avoid any allocation", the solution by #Speed8ump is your first choice! But then you will not have your double * result; anymore. You will be turning your "offline" solution (calculates the whole array first, then use the array elsewhere) to an "online" solution (calculates values as they are needed). This is a good refactoring to avoid memory allocation.
This answer to this question relies on the lifetime of the doubles you want pointers to. Consider:
// "pointless" because it takes no input and throws away all its work
void pointless_function()
{
double foo = 3.14159;
int j = 0;
for (int i = 0; i < 10; ++i) {
j += i;
}
}
foo exists and has a value inside pointless_function, but ceases to exist as soon as the function exits. Even if you could get a pointer to it, that pointer would be useless outside of pointless_function. It would be a dangling pointer, and dereferencing it would trigger undefined behavior.
On the other hand, you are correct that if you have data in memory (and you can guarantee it will live long enough for whatever you want to do with it), it can be a great idea to get pointers to that data instead of paying the cost to copy it. However, the main way for data to outlive the function that creates it is to call new, new[], or malloc. You really can't get out of that.
Looking at the code you posted, I don't see how you can avoid new[]-ing up the doubles when you create story. But you can then get pointers to those doubles later without needing to call new or new[] again.
I should mention that pointers to data can be used to modify the original data. Often that can lead to hard-to-track-down bugs. So there are times that it's better to pay the price of copying the data (which you're then free to muck with however you want), or to get a pointer-to-const (in this case const double* or double const*, they are equivalent; a pointer-to-const will give you a compiler error if you try to change the data being pointed to). In fact, that's so often the case that the advice should be inverted: "there are a few times when you don't want to copy or get a pointer-to-const; in those cases you must be very careful."

How to return a float array in c and save it an array of floats to use later?

I have a C++ function which returns a std::vector<float>.
I am interfacing with some C code.
How do I change this C++ function so that it returns some pointer to a float array, and how do I save this returned array so that I can use it in my C code?
You can get a pointer to a "raw" array with std::vector::data or &my_vector[0] if C++11 is not available. However, if a vector operation forces the vector to be resized then the raw storage will move around in memory and this pointer will no longer be safe to use. If there is any possibility of this happening, you will need to allocate separate storage (e.g. by creating a copy of the vector) and provide a pointer to that instead.
Update: Woodrow's comment made me notice that you are actually after returning a pointer from a function. You can only return pointers to heap-allocated memory, so you cannot use a local vector (or any other type of stack-allocated memory) to do this.
From a C point of view, vector<float> does two things:
Contain some floats
Automatically free the memory it uses
Since 2 is an alien concept to C (nothing much happens automatically, certainly not freeing memory), there's no simple replacement. Basically you have three options. They are the same as the three options you have when you want functions to "return strings" in C, although here we need to tell the caller both a pointer and a length.
In my opinion, the third option is "the right answer", in the sense that it's the one you try first in your design, and if the design looks OK you stick with it. The first and second can be provided as convenience functions in cases where the calling code will really benefit from them, either wrapped around or alongside the third.
Return allocated memory
size_t c_wrapper(float **pResult) {
try {
std::vector<float> vec(cpp_function());
*pResult= (float*) std::malloc(vec.size() * sizeof(float));
if (!*pResult) { /* handle the error somehow */ }
std::copy(vec.begin(), vec.end(), *pResult);
return vec.size();
} catch (std::bad_alloc) { /* handle the error somehow */ }
}
Upside: Simple calling code.
Downside: The caller has to free the memory, even if the size is known in advance and the data would happily fit in a local array variable. Might be slow due to memory allocation.
Model: strdup (Posix)
Use shared static-duration resources
See jrok's answer:
size_t c_wrapper(float **pResult) {
try {
static std::vector<float> vec;
vec = cpp_function(); // or cpp_function().swap(vec) in C++03
*pResult = &vec[0];
return vec.size();
} catch (std::bad_alloc) { /* handle the error somehow */ }
}
Upside: Ridiculously simple calling code.
Downside: There is only one instance of save in the program, so the returned pointer only points to the correct data until the next time c_wrapper is called. In particular, this is very thread-unsafe. If the result is very large, then that memory is wasted from the time the caller no longer needs it until the time the function is next called.
Model: strtok, gethostbyname.
Write the data into a buffer provided by the caller
size_t c_wrapper(float *buf, size_t len) {
try {
std::vector<float> vec(cpp_function());
if (vec.size() <= len) {
std::copy(vec.begin(), vec.end(), buf);
}
return vec.size()
} catch (std::bad_alloc) { /* handle the error somehow */ }
}
Upside: Most flexible.
Downside: The caller has to pass in a big enough buffer (assuming cpp_function behaves consistently, caller can find out the size by calling the function with size 0 and a null pointer, get a big enough buffer from somewhere, then call the function again).
Model: strcpy, snprintf, getaddrinfo.
You could save the returned temporary vector in a vector object with static storage duration.
std::vector<float> foo()
{
return std::vector<float>();
}
float* call_foo_and_get_pointer()
{
static std::vector<float> save; // this line is executed only at the first
// call to enclosing function
save = foo();
return save.data(); // or &data[0]
}
The pointer returned from call_foo_and_get_pointer is guaranteed to stay valid until the next call to it.
#include <vector>
#include <iostream>
int main()
{
std::vector<float> vec;
vec.push_back(1.23);
vec.push_back(3.123);
int len = vec.size();
float *arr = new float[len];
std::copy(vec.begin(),vec.end(),arr);
for(int i = 0; i < sizeof(arr)/sizeof(arr[0]); ++i){
std::cout << arr[i] << "\n";
}
delete [] arr;
return 0;
}