copy matrix into where pointer points to in c++ - c++

How to copy a matrix into where a pointer points to?
I am new in c++. I tried a lot but I could not find any solution.
here is my code:
float *output = new float[HighRange];
output = new float[10 * 10];
for(int i=0; i<10; i++){
for(int j=0; j<10; j++){
output[j]=input[i][j]; ---> I have error in this line
Thanks in advance

There are several ways to arrange the elements of input in output. Here is one way:
output[i*10 + j] = input[i][j]

Aside from NPEs suggestion, you have a memory leak here:
float *output = new float[HighRange]; // allocate contiguous block HighRange * sizeof(float) bytes
output = new float[10 * 10]; // allocate contiguous block 100 * sizeof(float) bytes
Aside from this being unnecessary, you leak memory, i.e. you allocate storage in the first statement that you never free before assigning a new value to the pointer that hold the first address to the previously allocated storage.
When allocating memory dynamically using new, you need to make sure you delete it accordingly. For arrays, you need to do the following:
float *output = new float[HighRange]; // allocate
delete [] output; // deallocate, note the delete[] operator
output = new float[10 * 10]; // allocate anew
Note: This is just to display correct usage of new/delete[]. By no means do I suggest your code would be any better if you handled deallocation in your example. :)

Related

resize an array of pointers without memory leak

I have a pointer to an array of pointers-to-objects, and need to resize the array. I do realize this is a perfect time to use vectors, But I'm not permitted to do so. My code works, but I don't completely follow what I've written, and concerned i may have created memory leaks:
void foo (DataSet &add_data)
{
if (sets == NULL)
{
sets = new DataSet*[1];
sets[0] = &add_data;
}
else
{
DataSet **transfer;
transfer = new DataSet*[num_of_sets];
for (int i = 0; i < num_of_sets; i++) // Copy addresses?
transfer[i] = sets[i];
delete [] sets; // Free the array.
sets = new DataSet*[num_of_sets + 1]; // Create new sets
for (int i = 0; i < num_of_sets; i++) // Copy back
sets[i] = transfer[i];
sets[num_of_sets] = &add_data; // Add the new set
delete [] transfer;
transfer = NULL;
}
num_of_sets++;
}
Why does Visual Studio throw an exception for:
for (int i = 0; i < num_of_sets; i++) // Copy addresses?
*transfer[i] = *sets[i];
but not:
for (int i = 0; i < num_of_sets; i++) // Copy addresses?
transfer[i] = sets[i];
But both code segments compile and run without fault in linux. This code should copy the pointers-to-objects. Is that what is happening with:
for (int i = 0; i < num_of_sets; i++) // Copy addresses?
transfer[i] = sets[i];
And do I need to be concerned if I want to free these objects with say a remove function later?
You do not need to allocate twice, just allocate once the final size:
transfer = new DataSet*[num_of_sets + 1]; // Create new sets - final size
for (int i = 0; i < num_of_sets; i++) // Copy addresses?
transfer[i] = sets[i];
delete [] sets; // Free the array.
sets = transfer;
sets[num_of_sets] = &add_data; // Add the new set
// now no need to delete[] transfer
That way you also get improved exception safety btw. - in your original code, you deleted the sets before allocating the new data to it - if that would throw std::bad_alloc, not only your object will become inconsistent (having a dangling sets ptr because you do not assign null to it after delete) but also the memory allocated to transfer would leak. If you allocate transfer directly to final size before delete[] sets, if that will throw, sets will stay intact and transfer will not leak (because it threw during allocation i.e. did not allocate).
Of course, make sure that you delete[] sets in the destructor (and maybe the pointers as well, in case your set is owning them).
*transfer[i] = *sets[i];
Does not copy addresses, like the other sample (without asterisks) does, it tries to dereference the uninitialized pointer elements of transfer and call operator= on DataSet objects on these addresses.
It's undefined behavior, that's why it appears to work under changed circumstances.

Freeing memory between loop executions

Hi I'm coding a C++ program containing a loop consuming too much unnecessary memory, so much that the computer freezes before reaching the end...
Here is how this loop looks like:
float t = 0.20;
while(t<0.35){
CustomClass a(t);
a.runCalculations();
a.writeResultsInFile("results_" + t);
t += 0.001;
}
If relevant, the program is a physics simulation from which I want results for several values of an external parameter called t for temperature. It seems that the memory excess is due to not "freeing" the space taken by the instance of my class from one execution of the loop to the following, which I thought would be automatic if created without using pointers or the new instruction. I tried doing it with a destructor for the class but it didn't help. Could it be because the main memory use of my class is a 2d array defined with a new instruction in there?
Precision, it seems that the code above is not the problem (thanks for the ones pointing this out) so here is how I initiate my array (by the largest object in my CustomClass) in its constructor:
tab = new int*[h];
for(int i=0; i<h; i++) {
tab[i] = new int[v];
for(int j=0; j<v; j++) {
tab[i][j] = bitd(gen)*2-1; //initializing randomly the lattice
}
}
bitd(gen) is a random number generator outputing 1 or 0.
And also, another method of my CustomClass object doubles the size of the array in the following way:
int ** temp = new int*[h];
for(int i=0; i<h; i++) {
temp[i] = new int[v];
for(int j=0; j<v; j++) {
temp[i][j] = tab[i/2][j/2];
}
}
delete[] tab;
tab = temp;
Could there be that I should free the pointer temp?
You're leaking memory.
Could there be that I should free te pointer temp?
No. After you allocate the memory for the new array of double size and copy the contents, you should free the memory that tab is pointing to. Right now, you're only deleting the array of pointers with delete [] tab; but the memory that each of those pointers points to is lost. Run a loop and delete each one. Only then do tab = temp.
Better still, use standard containers that handle memory management for you so you can forget messing with raw pointers and focus on your real work instead.

Deleting array pointers

SO,
I am running into an error which I cannot figure out (unless my understanding is just incorrect).
I have the following code:
int doubleSize=size*2;
int *newArr = new int[doubleSize];
for(int i=0; i<size; i ++) {
newArr[i]=jon[i];
}
size*=2;
display(newArr);
jon=newArr;
display(jon);
delete[] newArr;
display(jon);
After the first and second calls I get exactly what I want/expect. On the third display call the 0 and 1 indices are memory addresses, the rest of the values in the indices match the previous 2 calls. What could be causing this?
I also have another follow up question, with code as I have it, will not deleting jon[] cause the 'old' jon[] to stay in memory?
Thanks!
You have undefined behavior, so anything can happen.
int *newArr = new int[size*2];
// now newArr is a pointer to a memory area
jon=newArr;
// now jon is a pointer to the same area, whatever jon pointed to before is leaked
delete[] newArr;
// now the memory area no longer exists
display(jon);
// using jon is now illegal, it has the address of a deleted memory area
Probably the right solution is:
int *newArr = new int[doubleSize]; // allocate a new area
for( int i=0; i<size; ++i ) { // fill it in
newArr[i] = jon[i];
}
delete [] jon; // get rid of the old area we don't need anymore
jon = newArr; // now jon is linked to our brand new data in a brand new area
When you delete[] newArr, you're unallocating the memory at address newArr. Since jon is also pointing to that same memory (because you set jon = newArr), the memory is being overwritten with some other values (probably in your display function). What you need to do, is use some copy function (like memcpy) to copy the data to a newly allocated block at jon, not just point jon at the same spot as newArr.
The last display call is trying to display jon that is the same as newArr - what you have just deleted! Thus the behaviour will be undefined.

Reallocating 2D arrays on C++

lets say i have:
#include <iostream>
using namespace std;
int **a; //Global Variable
int main()
{
n=5;
a = new int*[n];
for ( int i = 0 ; i < n ; i++ )
a[i] = new int[n] ;
}
is there any realloc() method to increase the row size? (column size is fixed)
I mean if the row size is 5 then i wanna make it 6 not much more, just +1.
I use
for(i=0;i<n;i++)
{
counter++;
a[i] = (int *) realloc(a[i],counter*sizeof(int));
}
but i think something is wrong....
Edit: please don't advise any vector or sth like that.. Cuz i need my array as global.
realloc only works when you allocated with malloc. If you used new, you'll have to delete and then use new again (or just use something like a std::vector).
EDIT: Since you asked for an example of how to use malloc:
a = new int*[n];
would become
a = (int **) malloc (n * sizeof (int *));
and
a[i] = new int[n] ;
would become
a[i] = (int *) malloc (n * sizeof (int));
You can write your own routine to resize the array.
If you want a resized block with size N
allocate (new) the new size N
copy old array/block to this newly allocated array/block
free the old array (delete)
To avoid calling this routine again and again, better preallocate a large chunk, the size of chunk will be determined by the need of your application, and should be such which avoid resizing the array a lot of times.
The answer is No!
C++ memory management does not contain functionality for reallocating/resizing allocated memory. You would have to implement such a thing yourself using new/copy/delete semantics

JNI Java From C Memory Leak

It seems that following code is leaking memory. I checked the JVM memory utilization and it is not freeing up memory after subsequent calls. When I just run the Java as standalone it works fine for multiple calls and keeps deallocating memory just fine.
I would really appreciate any help.
jobjectArray my_obj = (jobjectArray) env->CallObjectMethod(cls, mid, qstr, pstr);
length = env->GetArrayLength(my_obj);
//printf("\nArray Length = %d \n", length);
char result[256];
const char *cstr;
int numberOfCharsInThisRow = 0;
array1 = (char **)malloc(length * sizeof(char *));
/*Check if pointer is null, if not then free its memory first*/
for(int i=0; i< length ; i++){
cstr = env->GetStringUTFChars((jstring)env->GetObjectArrayElement(my_obj,i), 0);
numberOfCharsInThisRow = std::strlen(cstr)+1;
*(array1+i)=(char *)malloc(numberOfCharsInThisRow * sizeof(char));
std::strcpy(result, cstr);
std::strcpy(*(array1+i),result);
env->ReleaseStringUTFChars((jstring)env->GetObjectArrayElement(my_obj,i), cstr);
}
env->DeleteLocalRef(my_obj);
}
//printf("\n\nDestroy JVM\n\n");
//jvm->DestroyJavaVM();
}
void libdeallocatememory(char **array1,int length)
{
//printf("Free Array memory \n");
for (int j=0 ;j <length ;j ++)
{
free(array1+j);
}
free(array1);
}
You should free the array1 pointers once you are done with them. What does this function do in reality? From the functionality I understood, you are copying from the java to a c pointer. What happens next? By calling ReleaseStringUTF, you are notifying the JVM that it isnt being used in native and so can be GCed when required
Think I have found the problem. Releasing Code should be something like
for (int j=0 ;j<length; j++ )
{
free(array1[j]);
}
free(array1);
The initial allocation should be array1 = (char **)malloc(length * sizeof(int *));
The difference is int* instead of char*. This is because this array is just an array of pointers. Pointer size is int. The next level is in the loop where you allocate memory for your strings. It should be array1[i] = (char *)malloc(numberOfCharsInThisRow * sizeof(char));
That means initially you allocated an array of pointers. Now for each element of that arary, you are allocating the memory to hold its own string. I think even *(array1+i) will work, but I find this more easy to read. So when you free, first you free the individual array elements you allocated, and then the entire array which you allocated initially. As an example, take a look at your current deallocate function. There is no difference between the free when j=0 and the last free. I am surprised you are not getting any crashes.
Take a look at http://c-faq.com/~scs/cclass/int/sx9b.html
Also try the following jstring myString =env->GetObjectArrayElement(my_obj,i); Use myString to get the UTFChars, Then call env->ReleaseStringUTFChars(mystring, cstr)