My c++ function is destroying variables when it shouldn't be - c++

The purpose of this function is to take a struct, and enlarge the array by 1. It does this by copying the array to a temporary array, deleting and recreating the original with a larger size. My problem is that when I run the function, all of my values within the struct become '-17891602'.
Correct me if I'm wrong, but I believe that this is the value that shows when the variable has been deleted? I can't figure out the problem. But here's the definition.
void Array::addValueStruct(int id, int size, int type, int compareValue, StoredData temp[])
{
//struct
StoredData* tempStruct = new StoredData [arrSize+1];
for (int i=0;i<arrSize;i++)
{
tempStruct[i] = temp[i];
}
arrSize = arrSize + 1;
delete [] temp;
temp = tempStruct;
temp[arrSize-1].id = id;
temp[arrSize-1].size = size;
temp[arrSize-1].type = type;
temp[arrSize-1].compareValue = compareValue;
}
Also, not sure if this is helpful, but the function call.
test.addValueStruct(5,5,5,5,testData);
UPDATE: Problem solved!

The issue is that the array pointer is passed into the function by value. This means that when you reassign it to point to a different array, this change does not propagate back to the caller.
You need to pass it either by pointer or by reference.

You are passing temp by value. Therefore, addValueStruct gets its own copy and changes made to it are not visible outside that function scope.

The problem probably is this line here:
temp = tempStruct;
Here you only changing the local copy of the temp variable. If you want to modify the variable used for the call you have to pass it by reference.

Related

Save memory data from function pointers c++

I do have a function and I need it to be of void type and to pass and get back its pointers:
void cracking::decompose(char input[][100], int size_S, double* &Atm, int* &ID, int &size_out);
{
vector<double> AtmD;
vector<int> XsD;
...
Atm = &AtmD[0];
ID = &XsD[0];
size_out = size(AtmD);
}
My Idea here is to get the address of the first value of the Vectors and with its size I may be able to get all the values, however when I call it in the main function it builds but the data in this memory adress is deleted and I get only garbage. Is there a way that I Maintain the data associated to these pointers?
here is how the function is called in the main:
int main()
{
char oi[900][100] = { "1 0.5 C", "2 0.55 N", "3 .5 S" };
double* xAtm = NULL;
int* xXs = NULL;
int tamanho;
cracking calc;
calc.decompose(oi, 3, xAtm, xXs, tamanho);
return 0;
}
Local variables will disappear after execution leaves the function. You can't return their address because deleted objects don't have an address.
The compiler may use registers for the local variables. Registers don't have useful addresses.
If you want to return the address of a variable, declare it as static:
double * some_function(void)
{
static double pi = 3.14159264;
return π
}
Another alternative is to declare the variable in dynamic memory and return the pointer:
double * another_function()
{
double * p_pi = new double(3.14159264);
return p_pi;
}
I think I understand your question, but i'm not entirely sure. I am assuming you are asking about returning the pointers to a few local variables inside of another function. I think something that you need to understand here is how the stack works. When you call your decompose function, you create a new frame on the stack, with a return address to main. All the local variables will be pushed onto the stack. Once the decompose function returns, that stack space is free to be reused again.
Is there a way that I Maintain the data associated to these pointers?
Yes! Allocate your variables on the heap. Look up new in C++. Hope this helps point you in the right direction!

C++ passing reference to array to C function

I'm trying to call a function written in C which passes in a pointer to an array.
In C++ I have the following:
double* x = new double[10];
populateArray(x);
In C:
void populateArray(double* vars);
{
vars = (double*) malloc(10*sizeof(double));
int i;
for(i = 0; (i < 10); i++)
{
vars[i] = 1*20;
}
}
However, when I try to output the contents of x inside the C++ code, the result is always 0?
Problem arises because you are changing local variable vars.
Change to:
double* x; //you don't need to allocate here if you are allocating later
populateArray(&x);
And:
void populateArray(double** vars)
{
*vars = malloc(10*sizeof(double)); //also no need to cast malloc
int i;
for(i = 0; (i < 10); i++)
{
(*vars)[i] = 1*20;
}
}
void populateArray(double* vars);
{
vars = (double*) malloc(10*sizeof(double)); // <---- remove this line completely
The problem is you're ignoring the vars you were given and creating a brand new buffer for it.
Worse, that buffer pointer gets lost when this function returns, causing a memory leak.
Just use the vars you were given -- delete the line indicated above.
Short answer: Remove the malloc call inside the function.
Slightly longer answer:
You're changing the value of the vals pointer to another newly allocated memory -- thus, the argument you pass in gets unused (and thus is never populated).
The result being always 0 is a coincidence, it could be anything (or you could end up with nasal demons) because you're then reading uninitialized memory, which is undefined behavior.
This of it as this, if you remove the call:
vals = new double[10];
vals = malloc(10 * sizeof(double));
The first value is overwritten.

C4700: uninitialized local variable

When I compile this code it says "error C4700: uninitialized local variable 'b' used". I'm not sure what I have to do now to fix this problem. I'm neither an IT student or technican but I very like to learn C++ and I'm learning it by myself. I've been on this for 1 day.
Many thanks
#include <stdio.h>
#include <iostream>
//A.
//1--
void InputArray(int *a, int &n)
{
printf("Insert n = ");
scanf("%d", &n);
a = new int[n];
for (int i=0; i<n; i++)
{
printf("Enter the key's a[%d] values: ", i);
scanf("%d",&a[i]);
}
}
void main()
{
int *b, m;
InputArray(b, m);
}
b is passed by value, which means a copy will be made, but since it's not initialized, you get the warning. Simply initialize it:
int *b = nullptr;
or
int *b = NULL;
If you want the function to modify the caller's variable, then pass by reference:
void InputArray(int *&a, int &n)
^
Your version passes the uninitialised pointer by value; the function modifies a local copy of it, but leaves b in its uninitialised state.
The pointers are not default initialized, so your variable b is uninitialized, this is the source of error. You have to initialize this variable to fix this:
void main()
{
int *b = NULL, m;
InputArray(b, m);
}
After you fix this there is additional problem in your code. It seems from the way you call a function that you expect to persistently change pointer b passed into it, so that b will point into memory allocated with new after function returned. But you pass a pointer by value what means changes made in function will not be reflected in original variable b which will still point to what it pointed before the call to a function. (the array will be allocated inside function and will stay in memory after function returned but you will leak this memory as b won't point into it). To fix this you have to pass pointer by reference:
void InputArray(int*& a, int& n)
Also: where is delete? Remember: mapping new to delete is bijection: every new corresponds to single delete placed somewhere in code.
First of all, did you learn how to use an pointer correctly ? because if you know how to use pointer u should know that when you declare a pointer you need to be initialized to NULL before you can use it, correct me if i'm wrong.
Example
int *b = nullptr;
int *b = NULL;
int *b = 0;
int *b(0);
It's all the same thing but in an different way

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

Pass pointer array address to function and update data in the address

I am pretty weak in understanding and working with pointers. So, Please help me here.
My objective is to pass an array pointer's address to a function ,(i.e.) the address the pointer is pointing to, and update the values directly in the address using the '*' operator, in the function, to avoid any return values. Moreover, the length of this array has to be changed dynamically in the function to which it is passed. This is my attempt. If there's a better method to update the value of an variable, without having it returned from a function, please do mention that to help me.
But am getting errors, as I know I am doing it wrong, but still wanted to try with what I know, since I thought the best way to learn is to do and make as many mistakes as possible. Please help me here
This is the main function
int main()
{
double *trans;
int *rots;
readctrls(rots,trans);
for(int i=0;i<trans.size();i++)
{
cout<<trans[i]<<endl<<rots[i];
}
}
Here, am trying to pass the address of the pointer arrays to the function readctrls. then later, print its values. I haven't mentioned a size, cuz it will be determined later in the function.
The function is just to read numbers from a text file, line by line and store these numbers in these 2 arrays. The readctrls function is as follows.
void readctrls(int*& rots,double*& trans)
{
fstream inputs;
inputs.open("input_coods.txt");
int nol = 0,i = 0;
string line,temp,subtemptrans,subtemprots;
while(getline(inputs,line))
{
++nol;
}
cout<<nol<<endl;
inputs.close();
inputs.open("input_coods.txt");
string *lines = new (nothrow) string[nol];
trans = new double[nol];
rots = new int[nol];
for(int i = 0; i<nol ; i++)
{
getline(inputs,lines[i]);
temp = lines[i];
for(int j = 0; j<temp.length() ; j++)
{
if(temp.at(j) == ' ')
{
subtemptrans = temp.substr(0,j);
subtemprots = temp.substr(j+1,temp.length()-j);
trans[j] = ::atof(subtemptrans.c_str());
rots[j] = atoi(subtemprots.c_str());
}
}
}
inputs.close();
}
Thanks a lot for your help guys. I was able to understand a bit and changed the code and was able to compile now without errors. however, the value I read from file and load into the array, doesn't seem to get reflected back in the main. Am getting the correct values from the file when I print the array in the function, but am getting zeros, when I print in the main(). Please help me here.
These are the contents of the file
0.2 0
0.2 0
0.2 0
0.2 0
0.2 0
while print 'trans', which takes the first number every line, in the function, am getting the correct values. But while printing in the main function
0
0
0
0.2.
I changed the pointer to pointer reference while passing to function. Please check edit in the function code. Thanks in advance.
The declaration
void readctrls(int &rots,double &trans)
tells the compiler that rots and trans are references to a single value each. They are not pointers.
To make matters worse, you are actually trying to pass a pointer-to-pointer as arguments when calling this function.
You should change the declaration to actually take pointers:
void readctrls(int* rots, double* trans)
then change your call to not use the address-of operator (as those are already pointers):
readctrls(rots, trans);
Your code has several errors. Here are some of them:
double *trans = new double[];
int *rots = new int[]; //^^You need to give the size
for(int i=0;i<trans.size();i++)
{
cout<<*trans[i]<<endl<<*rots[i];
}
trans and rots are simply array of double and integers, you simply use trans[i] to print the i-th element. Dynamic arrays should be used similarly to static arrays. Take a look at this pointer and arrays for some basic understanding. Meanwhile, look at dynamic memory in C++ for some understanding on this point.
void readctrls(int &rots,double &trans);
//^^expects reference to int and double while you are not passing int and double from main
An array and a pointer can be thought about similarly as a way of referring to a range in memory. If you want to refer to a range of memory via pointers, then just pass the pointer to the function, ie
double pd* = new double[10];
fun(pd);
...
void fun(double* pd, int numDoubles)
{
do {
double d = magicDoubleGenerator();
*pd = d; // read as "the value that pd points to" or "contents of pd"
} while (++pd < pd + numDoubles);
}
Pointers are hard until one day you realize "Ahh! they just point at things!"
There are many errors ...
inputs.open("input_coods.txt"); // second argument is missing
check this fstream open
void readctrls(int &rots,double &trans)
change to
void readctrls(int* rots, double* trans) // this creates pointer rots trans
*trans = new double[nol]; // remove *
*rots = new int[nol]; // remove *
double *trans = new double[]; // not specified the size
int *rots = new int[]; // not specified the size
readctrls(&rots,&trans); // this means you passing address of pointer
trans.size() ; // this is c++ double is not a class
I am recommending you to study c++ from this site C++ Tutorial