Resizing an array by pointer - c++

I am resizing an array inside of a method, but since I am using a pointer, the memory address is now incorrect. The diffDataTot pointer is initially created in main(), and then passed into the calculateField() method. The calculateField() method contains new information that needs to be added to diffDataTot, and some old information needs to be removed. I indicated this using the resize() method call.
void calculateField(diffData* diffDataTot){
diffData* filler = (diffData*)malloc(newSize * sizeof(diffData));
filler = resize(newSize, diffDataTot);
free(diffDataTot);
diffDataTot = filler;
free(filler);
}
int main{
diffData* diffDataTot = (diffData*)malloc(sizeof(diffData));
calculateField(diffDataTot);
}
I had to abbreviate this since it is from a full scale simulation that is thousands of lines. However, the issue is that diffDataTot contains the correct information locally inside of the calculateField() method. But the pointer points to a different address in memory than in main(). I could try without using a pointer, but I would like to avoid copying the entire array every time calculateField() is called since it is quite large.
Is there any way for me to pass back the memory of the first element in the array from the calculateField() method?

You need to pass the address of your pointer (pointer on pointer).
void
resizing_func(int **elements,
int *elem_count)
{
//---- get rid of additional indirection ----
int *p=*elements;
int count=*elem_count;
//---- work with local variables ----
// ...
int new_count=2*count; // whatever is needed for the problem
p=realloc(p, new_count*sizeof(int));
// ...
//---- make changes visible in calling context ----
*elements=p;
*elem_count=new_count;
}
void
testing_func(void)
{
int count=100;
int *elements=malloc(count*sizeof(int));
// populate elements
resizing_func(&elements, &count);
// use updated elements and count
}
Depending on the problem, realloc() can be replaced by:
allocate a second buffer,
work with first and second buffer,
free the first buffer and continue with the second,
as in the OP's question.
(by the way, notice that free(filler) will free what was intended to be kept in diffDataTot)
note: as the question is tagged c++, it would have probably been better to use a std::vector and pass it by (non-const) reference; but the provided source code looks like c.

Related

practical explanation of c++ functions with pointers

I am relatively new to C++...
I am learning and coding but I am finding the idea of pointers to be somewhat fuzzy. As I understand it * points to a value and & points to an address...great but why? Which is byval and which is byref and again why?
And while I feel like I am learning and understanding the idea of stack vs heap, runtime vs design time etc, I don't feel like I'm fully understanding what is going on. I don't like using coding techniques that I don't fully understand.
Could anyone please elaborate on exactly what and why the pointers in this fairly "simple" function below are used, esp the pointer to the function itself.. [got it]
Just asking how to clean up (delete[]) the str... or if it just goes out of scope.. Thanks.
char *char_out(AnsiString ansi_in)
{
// allocate memory for char array
char *str = new char[ansi_in.Length() + 1];
// copy contents of string into char array
strcpy(str, ansi_in.c_str());
return str;
}
Revision 3
TL;DR:
AnsiString appears to be an object which is passed by value to that function.
char* str is on the stack.
A new array is created on the heap with (ansi_in.Length() + 1) elements. A pointer to the array is stored in str. +1 is used because strings in C/C++ typically use a null terminator, which is a special character used to identify the end of the string when scanning through it.
ansi_in.cstr() is called, copying a pointer to its string buffer into an unnamed local variable on the stack.
str and the temporary pointer are pushed onto the stack and strcpy is called. This has the effect of copying the string(including the null-terminator) pointed at from the temporary to str.
str is returned to the caller
Long answer:
You appear to be struggling to understand stack vs heap, and pointers vs non-pointers. I'll break them down for you and then answer your question.
The stack is a concept where a fixed region of memory is allocated for each thread before it starts and before any user code runs.
Ignoring lower level details such as calling conventions and compiler optimizations, you can reason that the following happens when you call a function:
Arguments are pushed onto the stack. This reserves part of the stack for use of the arguments.
The function performs some job, using and copying the arguments as needed.
The function pops the arguments off the stack and returns. This frees the space reserved for the arguments.
This isn't limited to function calls. When you declare objects and primitives in a function's body, space for them is reserved via pushing. When they're out of scope, they're automatically cleaned up by calling destructors and popping.
When your program runs out of stack space and starts using the space outside of it, you'll typically encounter an error. Regardless of what the actual error is, it's known as a stack overflow because you're going past it and therefore "overflowing".
The heap is a different concept where the remaining unused memory of the system is available for you to manually allocate and deallocate from. This is primarily used when you have a large data set that's too big for the stack, or when you need data to persist across arbitrary functions.
C++ is a difficult beast to master, but if you can wrap your head around the core concepts is becomes easier to understand.
Suppose we wanted to model a human:
struct Human
{
const char* Name;
int Age;
};
int main(int argc, char** argv)
{
Human human;
human.Name = "Edward";
human.Age = 30;
return 0;
}
This allocates at least sizeof(Human) bytes on the stack for storing the 'human' object. Right before main() returns, the space for 'human' is freed.
Now, suppose we wanted an array of 10 humans:
int main(int argc, char** argv)
{
Human humans[10];
humans[0].Name = "Edward";
humans[0].Age = 30;
// ...
return 0;
}
This allocates at least (sizeof(Human) * 10) bytes on the stack for storing the 'humans' array. This too is automatically cleaned up.
Note uses of ".". When using anything that's not a pointer, you access their contents using a period. This is direct memory access if you're not using a reference.
Here's the single object version using the heap:
int main(int argc, char** argv)
{
Human* human = new Human();
human->Name = "Edward";
human->Age = 30;
delete human;
return 0;
}
This allocates sizeof(Human*) bytes on the stack for the pointer 'human', and at least sizeof(Human) bytes on the heap for storing the object it points to. 'human' is not automatically cleaned up, you must call delete to free it. Note uses of "a->b". When using pointers, you access their contents using the "->" operator. This is indirect memory access, because you're accessing memory through an variable address.
It's sort of like mail. When someone wants to mail you something they write an address on an envelope and submit it through the mail system. A mailman takes the mail and moves it to your mailbox. For comparison the pointer is the address written on the envelope, the memory management unit(mmu) is the mail system, the electrical signals being passed down the wire are the mailman, and the memory location the address refers to is the mailbox.
Here's the array version using the heap:
int main(int argc, char** argv)
{
Human* humans = new Human[10];
humans[0].Name = "Edward";
humans[0].Age = 30;
// ...
delete[] humans;
return 0;
}
This allocates sizeof(Human*) bytes on the stack for pointer 'humans', and (sizeof(Human) * 10) bytes on the heap for storing the array it points to. 'humans' is also not automatically cleaned up; you must call delete[] to free it.
Note uses of "a[i].b" rather than "a[i]->b". The "[]" operator(indexer) is really just syntactic sugar for "*(a + i)", which really just means treat it as a normal variable in a sequence so I can type less.
In both of the above heap examples, if you didn't write delete/delete[], the memory that the pointers point to would leak(also known as dangle). This is bad because if left unchecked it could eat through all your available memory, eventually crashing when there isn't enough or the OS decides other apps are more important than yours.
Using the stack is usually the wiser choice as you get automatic lifetime management via scope(aka RAII) and better data locality. The only "drawback" to this approach is that because of scoped lifetime you can't directly access your stack variables once the scope has exited. In other words you can only use stack variables within the scope they're declared. Despite this, C++ allows you to copy pointers and references to stack variables, and indirectly use them outside the scope they're declared in. Do note however that this is almost always a very bad idea, don't do it unless you really know what you're doing, I can't stress this enough.
Passing an argument by-ref means pushing a copy of a pointer or reference to the data on the stack. As far as the computer is concerned pointers and references are the same thing. This is a very lightweight concept, but you typically need to check for null in functions receiving pointers.
Pointer variant of an integer adding function:
int add(const int* firstIntPtr, const int* secondIntPtr)
{
if (firstIntPtr == nullptr) {
throw std::invalid_argument("firstIntPtr cannot be null.");
}
if (secondIntPtr == nullptr) {
throw std::invalid_argument("secondIntPtr cannot be null.");
}
return *firstIntPtr + *secondIntPtr;
}
Note the null checks. If it didn't verify its arguments are valid, they very well may be null or point to memory the app doesn't have access to. Attempting to read such values via dereferencing(*firstIntPtr/*secondIntPtr) is undefined behavior and if you're lucky results in a segmentation fault(aka access violation on windows), crashing the program. When this happens and your program doesn't crash, there are deeper issues with your code that are out of the scope of this answer.
Reference variant of an integer adding function:
int add(const int& firstInt, const int& secondInt)
{
return firstInt + secondInt;
}
Note the lack of null checks. By design C++ limits how you can acquire references, so you're not suppose to be able to pass a null reference, and therefore no null checks are required. That said, it's still possible to get a null reference through converting a pointer to a reference, but if you're doing that and not checking for null before converting you have a bug in your code.
Passing an argument by-val means pushing a copy of it on the stack. You almost always want to pass small data structures by value. You don't have to check for null when passing values because you're passing the actual data itself and not a pointer to it.
i.e.
int add(int firstInt, int secondInt)
{
return firstInt + secondInt;
}
No null checks are required because values, not pointers are used. Values can't be null.
Assuming you're interested in learning about all this, I highly suggest you use std::string(also see this) for all your string needs and std::unique_ptr(also see this) for managing pointers.
i.e.
std::string char_out(AnsiString ansi_in)
{
return std::string(ansi_in.c_str());
}
std::unique_ptr<char[]> char_out(AnsiString ansi_in)
{
std::unique_ptr<char[]> str(new char[ansi_in.Length() + 1]);
strcpy(str.get(), ansi_in.c_str());
return str; // std::move(str) if you're using an older C++11 compiler.
}

Transfer Data from Pointer to Local Array to Global Array Without Using For Loop

I have a function which retrieves an image from a camera.
This function has a function called GetData() which returns a pointer to the data contained by the Image object created by the camera.
The data pointed to by GetData() is locally initialized.
Currently, I'm copying the data pointed to by GetData element by element using a for loop, but is there a way to copy the data without using a for loop? Or, better yet, avoid copying the data and just copy the pointer address and prevent the local data from being terminated.
Code:
void getImage(unsigned char data[]){
// Get the image in 1d array format
fc::Image rawImage;
//Initializes Image object
error = camera.RetrieveBuffer( &rawImage );
//retrieve and return data
unsigned char *temp = rawImage.GetData(); //returns point to data
for(int i = 0; i < IMG_SIZE; i++){
data[i] = temp[i];
}
}
Called simply with
unsigned char data[size];
getImage(data);
The problem lies in the fact that your data is a local object on the stack. Once your function returns, the fc::Image object (and the data it points to) will be destroyed. I only see three possible ways of getting that data out of the function:
Copy the data to the destination array (like you already do, but maybe using memcpy or something along those lines instead of a naked for loop)
Declare your data member to be static (so it sticks around even after the function returns), then simply set the value of the destination pointer to point to the data by data = rawImage.GetData()
Possibly the best one, if you can do it: change your API! Simply accept a pointer or reference to an fc::Image object and pass that as the argument to camera.RetrieveBuffer so your data lands in the right place to begin with. Or another way would be to return your object by value, and take no arguments in that case.
The second one is kind of funky, since the data would only be valid as long as someone else doesn't call the function again, which is a terrible practice to be honest, so I wouldn't suggest number 2.
Also, this API is pretty bad as it is. What's the guarantee that the passed in pointer will have enough capacity? And also, how does the user know how long is the data they received? You don't return a size value or anything.
EDIT:
There's a more appropriate way of doing number 2. You can do something like this:
#include <unordered_map>
// Ideally this would be wrapped in a class or something. Don't use globals.
std::unordered_map<unsigned char*, fc::Image> images;
void getImage(unsigned char data*){
// Get the image in 1d array format
fc::Image rawImage;
//Initializes Image object
error = camera.RetrieveBuffer( &rawImage );
data = rawImage.getData();
images.insert(std::make_pair(data, move(rawImage)));
}
This uses an unordered_map to keep your local objects alive, so you can safely return pointers into them without having to worry about the lifetime of the objects.
But in this case you will have to create a cleanup function as well:
void destroyImage(unsigned char data*){
images.erase(data);
}
Since the map will keep your objects around forever, you will soon start to fill up memory if you keep getting new images. If you use this method, then your users will have to call destroyImage() as soon as they no longer need the data to avoid leaking memory essentially. This kind of goes agains the memory management guidelines in modern C++ which encourage automatic cleanup, while this would depend on your users to call your cleanup function, which is a little unsafe, but it's still the best you can do in my opinion, since you cannot change your API.
If you can expand your API to include such a function, this is definitely a better way to extend the lifetime of your local objects, rather than marking them static.

Making function that can get as parameter &var or var

I would like to create a function so I can use it in both ways -
I know that my wording is was not good so I deleted it (Because it will cause only confusion) and leaving only the code with the notes inside it:
int CalculationFunc(int i1, int i2, int i3, int i4, int i5) {
/* Some calculation done here */
return (i2*i3)+i5-i2+i4; /* <- this is not good example.. the calculation will be based also on
on values that are changing from time to time.. */
}
int main() {
// Situation 1:
/* In this situation I didn't initialized any parameter before because I didn't
need to.. all I need is to call to the functions with predefined values */
int iAnswer1 = CalculationFunc(1, 2, 3, 4, 5);
/*^ Everything is fine in this case - I Allocate memory only once*/
// ----------------------------------------------------------
// Situation 2:
int iVal1 = 0, iVal3 = 0, iVal5 = 0; // <-- Memory is allocated
/* ... something done here so the values of are not constant ...
(The code for this is not written) */
/*In this situation something different: some values that I going to pass to the
function are not predefined, and they are outcome of some pre-calculation done before,
so there is allocated memory for them. If I call to the functions with these variables: */
int iAnswer2 = CalculationFunc(iVal1, 6, iVal3, 2, iVal5);
/* ^ There is not really a "real-world" problem here. the problem is that what happening
In low-level is this:
a) allocate memory for iVal1 , iVal3 , iVal5
b) copy value of iVal1 to the allocated memory (and the same for iVal3 and iVal5)
c) use the allocated memory..
This is not efficient. What I want to do is to pass pointers for iVal1, iVal3, iVal5
And the function will automatically get the data using the pointers.
So there will not be steps a and b.
This is how I want to call it:
CalculationFunc(&iVal1, 6, &iVal3, 2, &iVal5)
*/
return 0;
}
Thanks for helpers!
You could overload the function to take different sets of parameters as references (or plain pointers), but you would end up with a lot of unnecessary copies of the same piece of code.
If you are planning to do this just for the sake of performance, I advice you not to. You are probably not going to get any performance boost from that, not with such simple data types.
This is better because this way the function does not necessarily require to allocate memory (for just a copy value) to transfer the same data.
When you're passing a variable by a reference or a pointer, the address to the variable needs to be copied. And when the data type of the variable you are referring to is int, the address is about the same size as the variable itself, so passing a pointer to an int is not any faster than passing the int itself. Actually, it is probably slower, because the pointer then needs to be dereferenced when the value is used in the function.
For a data type with larger size passing by pointer/reference could be significantly faster, but not with ints.

copying the value of a const uint * to another variable in c++

I have a generic problem I suppose.
I`m currently learning C++ and SDL 2.0. SDL provides a function which returns a pointer to a const uint * containing all the keystates.
These are the variables I would like to use:
const Uint8* oldKeyState;
const Uint8* currentKeyState;
In the construction of my input.cpp:
currentKeyState = SDL_GetKeyboardState(&this->length);
oldKeyState = currentKeyState;
And in the Update() method I use:
oldKeyState = currentKeyState;
currentKeyState = SDL_GetKeyboardState(NULL);
However, instead of copying over the last values, all I do is giving a pointer to the oldKeyState, which in turn points to the current keystates..
So how do I go about copying the actual values from the variable's pointer to the current and old keystate? I don't want the pointer in my old keystate since I will not be able to check whether the previous state was UP and the new state is DOWN.
Uint8 oldKeyState[SDL_NUM_SCANCODES];
// ...
memcpy(oldkeystate, currentKeyState, length);
The signature of the function you're calling is
const Uint8* SDL_GetKeyboardState(int* numkeys)
This function has return type const Uint8*, which means it returns a pointer to byte(s). (It does not return a pointer to a pointer.) According to the documentation, this returned pointer actually points to an array of Uint8 (one Uint8 is not big enough to encode the states of all the keys on the keyboard), and the value pointed to by numkeys is overwritten with the length of that array (ie. the number of keys). So to preserve the values in the array, you need to allocate a region of memory the same length as gets stored in this->length, and then copy that memory from SDL's array to your own. Then you'll want to keep a pointer to your own array around for you to continue to use. Because SDL says that the returned pointer to the array is valid for the entire lifetime of the application, you may assume that the length is unchanging, so you don't need to worry about resizing your array, but you should worry about deallocating that memory when you're done with it.
So, I think SDL is mostly a C library.
The const Uint8* returned by SDL_GetKeyboardState is a pointer to the first element in an array in values.
If you want to copy a given state for later reference, you would generally need an array to copy them to, and a for loop to do the copying. eg:
currentKeyState = SDL_GetKeyboardState(&this->length);
savedKeyState = malloc(this->length*sizeof(Uint8));
for(int i=0; i<&this-length, i++) savedKeyState [i] = currentKeyState[i];
Of course that pretty poor code, using a vector might be a better way to go, something like:
currentKeyState = SDL_GetKeyboardState(&this->length);
vector savedKeyState(currentKeyState, currentKeyState+length);
The problem you have here is that you are trying to copy the pointer to a const array, which never changes. As a result, you will see that both pointers go to the same memory address, and you never have two copies of the input state which allows you to check for pressed keys.
Instead, you should use memcpy to copy one array to the other. But in order to do so, you should change the type of oldKeyState to just Uint8*, or else you will get an error for copying into a const array.
So, the code should end up like this:
const Uint8 * currentKeyState;
Uint8 * oldKeyState;
...
//Constructor
currentKeyState = SDL_GetKeyboardState(&this->length);
oldKeyState = new Uint8[this->length];
...
//Input update
memcpy(oldKeyState, currentKeyState, this->length);
SDL_PumpEvents(); //Copy the array before calling PumpEvents()!
currentKeyState = SDL_GetKeyboardState(NULL);

C++ Why is this passed-by-reference array generating a runtime error?

void pushSynonyms (string synline, char matrizSinonimos [1024][1024]){
stringstream synstream(synline);
vector<int> synsAux;
int num;
while (synstream >> num) {synsAux.push_back(num);}
int index=0;
while (index<(synsAux.size()-1)){
int primerSinonimo=synsAux[index];
int segundoSinonimo=synsAux[++index];
matrizSinonimos[primerSinonimo][segundoSinonimo]='S';
matrizSinonimos [segundoSinonimo][primerSinonimo]='S';
}
}
and the call..
char matrizSinonimos[1024][1024];
pushSynonyms("1 7", matrizSinonimos)
It's important for me to pass matrizSinonimos by reference.
Edit: took away the & from &matrizSinonimos.
Edit: the runtime error is:
An unhandled win32 exception occurred in program.exe [2488]![alt text][1]
What's wrong with it
The code as you have it there - i can't find a bug. The only problem i spot is that if you provide no number at all, then this part will cause harm:
(synsAux.size()-1)
It will subtract one from 0u . That will wrap around, because size() returns an unsigned integer type. You will end up with a very big value, somewhere around 2^16 or 2^32. You should change the whole while condition to
while ((index+1) < synsAux.size())
You can try looking for a bug around the call side. Often it happens there is a buffer overflow or heap corruption somewhere before that, and the program crashes at a later point in the program as a result of that.
The argument and parameter stuff in it
Concerning the array and how it's passed, i think you do it alright. Although, you still pass the array by value. Maybe you already know it, but i will repeat it. You really pass a pointer to the first element of this array:
char matrizSinonimos[1024][1024];
A 2d array really is an array of arrays. The first lement of that array is an array, and a pointer to it is a pointer to an array. In that case, it is
char (*)[1024]
Even though in the parameter list you said that you accept an array of arrays, the compiler, as always, adjusts that and make it a pointer to the first element of such an array. So in reality, your function has the prototype, after the adjustments of the argument types by the compiler are done:
void pushSynonyms (string synline, char (*matrizSinonimos)[1024]);
Although often suggested, You cannot pass that array as a char**, because the called function needs the size of the inner dimension, to correctly address sub-dimensions at the right offsets. Working with a char** in the called function, and then writing something like matrizSinonimos[0][1], it will try to interpret the first sizeof(char**) characters of that array as a pointer, and will try to dereference a random memory location, then doing that a second time, if it didn't crash in between. Don't do that. It's also not relevant which size you had written in the outer dimension of that array. It rationalized away. Now, it's not really important to pass the array by reference. But if you want to, you have to change the whole thingn to
void pushSynonyms (string synline, char (&matrizSinonimos)[1024][1024]);
Passing by reference does not pass a pointer to the first element: All sizes of all dimensions are preserved, and the array object itself, rather than a value, is passed.
Arrays are passed as pointers - there's no need to do a pass-by-reference to them. If you declare your function to be:
void pushSynonyms(string synline, char matrizSinonimos[][1024]);
Your changes to the array will persist - arrays are never passed by value.
The exception is probably 0xC00000FD, or a stack overflow!
The problem is that you are creating a 1 MB array on the stack, which probably is too big.
try declaring it as:
void pushSynonyms (const string & synline, char *matrizSinonimos[1024] )
I believe that will do what you want to do. The way you have it, as others have said, creates a 1MB array on the stack. Also, changing synline from string to const string & eliminates pushing a full string copy onto the stack.
Also, I'd use some sort of class to encapsulate matrizSinonimos. Something like:
class ms
{
char m_martix[1024][1024];
public:
pushSynonyms( const string & synline );
}
then you don't have to pass it at all.
I'm at a loss for what's wrong with the code above, but if you can't get the array syntax to work, you can always do this:
void pushSynonyms (string synline, char *matrizSinonimos, int rowsize, int colsize )
{
// the code below is equivalent to
// char c = matrizSinonimos[a][b];
char c = matrizSinonimos( a*rowsize + b );
// you could also Assert( a < rowsize && b < colsize );
}
pushSynonyms( "1 7", matrizSinonimos, 1024, 1024 );
You could also replace rowsize and colsize with a #define SYNONYM_ARRAY_DIMENSION 1024 if it's known at compile time, which will make the multiplication step faster.
(edit 1) I forgot to answer your actual question. Well: after you've corrected the code to pass the array in the correct way (no incorrect indirection anymore), it seems most probable to me that you did not check you inputs correctly. You read from a stream, save it into a vector, but you never checked whether all the numbers you get there are actually in the correct range. (end edit 1)
First:
Using raw arrays may not be what you actually want. There are std::vector, or boost::array. The latter one is compile-time fixed-size array like a raw-array, but provides the C++ collection type-defs and methods, which is practical for generic (read: templatized) code.
And, using those classes there may be less confusion about type-safety, pass by reference, by value, or passing a pointer.
Second:
Arrays are passed as pointers, the pointer itself is passed by value.
Third:
You should allocate such big objects on the heap. The overhead of the heap-allocation is in such a case insignificant, and it will reduce the chance of running out of stack-space.
Fourth:
void someFunction(int array[10][10]);
really is:
(edit 2) Thanks to the comments:
void someFunction(int** array);
void someFunction(int (*array)[10]);
Hopefully I didn't screw up elsewhere....
(end edit 2)
The type-information to be a 10x10 array is lost. To get what you've probably meant, you need to write:
void someFunction(int (&array)[10][10]);
This way the compiler can check that on the caller side the array is actually a 10x10 array. You can then call the function like this:
int main() {
int array[10][10] = { 0 };
someFunction(array);
return 0;
}