2D Array creation phase :
int **table = new int*[10];
for (int a = 0; a < 10; a++)
{
table[a] = new int[10];
for(int b = 0; b < 10; b++){
table[a][b] = 0;
}
}
2D Array deletion phase :
for (int i = 0; i < 10; i++)
{
delete [] table[i];
}
delete [] table;
I noticed something while debugging my code with GDB. All values from table[0][0] to table[0][3] are garbage but all values from table[0][4] to table[0][9] are all 0. This problem is Valid for all pointers from table[0] to table[9].
Then I thought there was a problem with GDB and I printed table[0][0] and table[0][5] to the screen. Indeed the value of table[0][0] is garbage, the value of table[0][5] is 0.
My question is does c++ actually freeing this data?
Yes, the data is actually being freed. If you dereference a pointer after its value is freed, you get undefined behaviour which might be its original value or some other garbage value.
Related
I'm trying to delete my 2D array, but I consistently get errors when I try to delete it, we have to work backwards so I delete the elements first, then the column array, then the row array. here is my code for the constructor in my class, MyMatrix:
private:
int m; //rows
int **ptr; //ptr to first dimension
int n; // columns
public:
MyMatrix() //constructor
{
m = 0;
n = 0;
ptr = new int*[m];
int *length_arr = new int[m];
for (int i = 0; i <= m-1; i++)
{
*(ptr+i) = new int[n];
*(length_arr+i) = n;
}
}
and my destructor looks like this:
for(int i = 0; i <= m-1; i++)
{
for (int j = 0; j <= n-1; j++)
{
delete ((*(ptr+i))+j);
}
delete[] *(ptr+i);
}
delete[] ptr;
the error I'm getting is:
assg7(2677,0x100de3d40) malloc: *** error for object 0x12d606804: pointer being freed was not allocated
I've wracked my brain for where I can fix this, for context, I'm doing an assignment with operator overloading. I specifically need a delete function to work properly for my = assignment overloading since I want to delete and again reallocate memory to equate two matrices, but the terminal is showing malloc errors and is thus not equating the matrices.
for additional info here is my = overloading code:
void operator = (const MyMatrix &obj)
{
if(n == obj.n && m == obj.m)
{
//for loop to equate elements in this-> to the elements of the passed object
}
else
{
for(int i = 0; i <= m-1; i++)
{
for (int j = 0; j <= n-1; j++)
{
delete ((*(ptr+i))+j);
}
delete[] *(ptr+i);
}
delete[] ptr;
// the code for assigning new memory according to the passed objects rows and colums goes here
//then for loop to equate elements in this-> to the elements of the passed object
}
}
thanks.
You have two "levels" of new, so three "levels" of delete can't be right.
Spell out your deletion loop, using indexing instead of pointer arithmetic:
First iteration:
delete ptr[0]+0;
delete ptr[0]+1;
...
delete ptr[0]+n-1;
delete [] ptr[0];
Second iteration:
delete ptr[1]+0;
delete ptr[1]+1;
...
delete ptr[1]+n-1;
delete [] ptr[1];
You're passing to delete a pointer to the first element of ptr[0], a pointer to the second element of ptr[0], a pointer to the third element of ptr[0], ...
But the things you allocated were ptr[0], ptr[1], ... ptr[m-1], not their individual elements.
Remove the innermost deletion loop.
(And don't mess around with pointer arithmetic when you can use indexing.)
I don't know how you would want to allocate memory space by m length if it is set to 0 by default.
To me it looks like you set m = 0 and then try to allocate by 0 length or how do you control the length of your dimensions?
Maybe edit your constructor to:
MyMatrix(int m, int n)
{
this->m = m;
this->n = n;
...
I have a function using a 2D array and I want to copy data from one array to another and I used a tmp array, but valgrind kept on saying I have memory leak. I can't figure out why. The following is part of a function.
// valgrind gave me error as operator new[] (unsigned long) for the following line
T** temp_pointer = new T*[rows];
for (int i=0; i < rows; i++) {
temp_pointer[i] = new T[columns];
}
for (int i =0; i< rows; i++) {
for (int j =0; j < (columns-3); j++) {
temp_pointer[i][j] = Arry[i][j];
}
temp_pointer[i][columns -3 ] = myvalue1;
temp_pointer[i][columns-2] = myvalue2;
temp_pointer[i][columns-1] = myvalue3;
}
for ( int i =0; i< rows; i++)
delete [] Arry[i];
delete [] Arry;
Arry= temp_pointer;
I also have a destructor which recursively delete the Arry pointers. Arry is private member of a template class.
I just could not figure out why it was a memory leak. Am I supposed to recursively delete temp_pointer ?? (I tried and it didn't work)
I just didn't know where did it leak?
It is not entirely clear why valgrind claims that the memory is being leaked, but you clearly have an out of bound access in your loop.
temp_pointer[i][columns] = myvalue;
The index of the last element of an array is not its size, it is (size-1). Writing into a location outside of the array's bound could clobber the memory allocator's housekeeping information and cause valgrind to complain.
In below code, I expect 1 to be initialized in all the 10 elements in x array. But, it doesn't seem to be working. May I know what I am missing here?
int main() {
int *x = new int[10];
for(int i =0; i <10; ++i){
*x = 1;
x++;
}
for(int i = 0; i < 10; ++i)
std::cout<<i<<" is "<<x[i]<<std::endl;
return 0;
}
By the time you end the initialization loop, your x is pointing beyond the last allocated element. Before second forloop you need to readjust x to point to start of memory
x -= 10;
Even better would be to keep your walking pointer as a copy
int *xcopy = x;
for(int i =0; i <10; ++i){
*xcopy = 1;
xcopy++;
}
Or use indexing to update the value
for(int i =0; i <10; ++i){
x[i] = 1;
}
You're incrementing x in the first loop, so after that it points past the end of the array. The second loop uses that new value to read from memory beyond the end, giving undefined behaviour.
The best option is to stop juggling pointers, with the bonus feature of fixing the memory leak:
std::vector<int> x(10, 1);
for(size_t i = 0; i < x.size(); ++i) {
std::cout<<i<<" is "<<x[i]<<std::endl;
}
Otherwise, you could assign to x[i] rather than *x in the first loop and leave x unmodified; or you use a copy of the pointer, or undo the modification after the loop.
Your code has undefined behavior, as you're accessing some random memory (you have changed x).
You should not change x (the pointer). Instead, you can use x[ i ] = 1; or use some other temp pointer to "loop over" x.
You can also decrement x, as #Mohit Jain states, but I wouldn't recommend changing where x points at all.
I get very frustrating error in following piece of code. Thats my array.
int **tab2 = new int*[3];
I allocate this like it.
for(i = 0; i < 10; i++) {
tab2[i] = new int[3];
tab2[i][0] = 40;
tab2[i][1] = 10;
tab2[i][2] = 100;
}
Then after using it i want to destroy it.
for(i = 0; i < 10; i++) {
delete [] tab2[i];
}
delete [] tab2;
And this causes core dump every single time. I tried many different ways to destroy it and every time get this error. What im making wrong here ?
This
int **tab2 = new int*[3];
does not do what you think it does.
You want an array that will contain TEN (10) pointers, each to an array of THREE ints.
new int*[3] is an array that contain THREE pointers.
What you want is this (live at coliru):
#include <iostream>
int main() {
int **tab2 = new int*[10];
for(int i = 0; i < 10; i++) {
tab2[i] = new int[3];
tab2[i][0] = 40;
tab2[i][1] = 10;
tab2[i][2] = 100;
}
for(int i = 0; i < 10; i++) {
delete [] tab2[i];
}
delete [] tab2;
}
With
int **tab2 = new int*[3];
you allocate an array of pointers of size 3. But than with
for(i = 0; i < 10; i++) {
tab2[i] = new int[3];
//...
}
you access it with up to index 9. That will surely go wrong.
The deletion process looks fine to me. To fix it, you should allocate an array of pointers with size 10instead of 3, e.g.
int **tab2 = new int*[10];
Looks like what you're trying to do is to create an N by M array, where N is known at runtime and M is fixed (in this case, 3).
Why not just do this?
{
std::array<int, 3> defaults = {{ 40, 10, 100 }};
std::vector<std::array<int, 3>> thing(10, defaults);
}
The vector, thing is automatically deallocated when it goes out of scope, and its size can be set at runtime. You still access the structure in the same way:
thing[1][2] = 3
Manual memory management can be easily avoided by using standard containers and smart pointers. Doing so will keep you code cleaner, and have fewer opportunities for dangling pointers and memory leaks.
I am getting a "Segmentation fault (core dumped)" run-time error with the following code:
#include <iostream>
#include "Student.h"
#include "SortedList.h"
using namespace std;
#define BOUNDS 100
int main() {
SortedList *list = new SortedList(); // points to the sorted list object
Student *create[BOUNDS]; // array to hold 100 student objects
int num = 100000; // holds different ID numbers
// fills an array with 100 students of various ID numbers
for (int i = 0; i < BOUNDS; i++) {
create[i] = new Student(num);
num += 10;
}
// insert all students into the sorted list
for (int i = 0; i < BOUNDS; i++)
list->insert(create[i]);
// individually deletes each student
num = 100000;
for (int i = 0; i < BOUNDS; i++) {
delete list->find(num);
num += 10;
}
// insert all students into the sorted list
for (int i = 0; i < BOUNDS; i++)
list->insert(create[i]);
num = 100000;
for (int i = 0; i < BOUNDS; i++) {
list->remove(num);
num += 10;
}
cout << "test2" << endl;
delete list;
return 0;
}
I have narrowed the error down to the delete list; lines (or whichever one comes first). I am just wondering as to why this is and how to possibly fix it. Any insight on this matter would be useful.
You have two problems that I can see.
First, in this loop:
for (int i = 0; i < BOUNDS; i++) {
x = new Student(num);
num += 10;
}
You are creating a bunch of dynamic Students and putting the latest one in x and the previous one is lost. This creates 100 Students dynamically and 99 of them are leaked. Also it doesn't fill an array with Students like the comment above it says it does. I'm not sure what you're trying to do here so I can't comment on what you need to do instead.
Secondly, you are calling delete here:
delete list->find(num);
on Students that are in automatic storage (the stack) (because you filled the list with pointers to the Students in create which holds automatic Students), which leads to undefined behaviour and is probably the cause of your segfault. You don't need to deallocate these Students because they will be deallocated when the array goes out of scope at the end of main.
Without knowing how StudentList is implemented, this is kind of shot in the dark but...
list->insert(&create[i]); is adding a stack allocated object to the list, and then delete list->find(num); tries to delete this stack allocated object. You can't delete stack allocated objects.
In addition to this, your first for loop is leaking memory.
And I've been ninja'd.
This line has a problem:
list->insert(&create[i]);
At that point, create has been allocated, but nothing has been put into it. Probably the result of x = new Student(num) should be assigned there.
"create" array is allocated on stack. You are trying to delete stack allocated memory that's why you getting this error.
delete list->find(num);
You are definitely leaking memory:
// fills an array with 100 students of various ID numbers
for (int i = 0; i < BOUNDS; i++) {
x = new Student(num);
num += 10;
}
The x is leaked in this snippet, unless the ctor of Student somehow magically inserts itself somewhere, where the pointer can be tracked.
And that might or might be related to the crash.