incorrect checksum for freed object - c++

I am getting this error (memory location varies between runs):
q2(4910,0x7fff7a1d4300) malloc: *** error for object 0x7fdf79c04bd8: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
This is the function that crashes:
public:
// construct a 'rows X cols' matrix.
SMatrix(int rows, int cols) {
if (rows<1 || cols<1) {
cout<<"Invalid row/col value(s).";
exit(-1);
}
this->_rows = rows;
this->_cols = cols;
this->_vertical = new simpleNode [rows];
this->_horizontal = new simpleNode [cols];
if (this->_vertical == NULL || this->_horizontal==NULL) {
cout<<"Exiting";
exit(-1);
}
initArrays();
}
It crashes on this particular line:
this->_horizontal = new simpleNode [cols];
The function that calls:
int main() {
SMatrix bigM(500,500);
bigM.setElement(10,20,17);
cout <<" bigM - total size in bytes: (implementation depended): "
<< bigM.sizeInBytes() << endl << endl;
SMatrix m1(7,10),m2(7,10),m4(10,2),m5(7,2); //Crashes on m4(10,2)
}
Other functions that could be relevant:
struct simpleNode {
Node* _next;
};
int _rows; //Number of rows in this SMatrix
int _cols; //Number of columns in this SMatrix
simpleNode * _vertical; //array (simpleNode)
simpleNode * _horizontal; //array (simpleNode)
/*Initiate the horizontal/vertical arrays to point to null*/
void initArrays() {
int i;
for (i=0; i<this->_rows; i++)
this->_horizontal[i]._next = NULL;
for (i=0; i<this->_cols; i++)
this->_vertical[i]._next = NULL;
}
I am on OSX. I compiled with -g and ran it with GDB but Program exited normally.
How can I debug this if I don't use XCode? Also a hint on how to fix the problem would be very helpful.
Edit: I'm running the output file and sometimes it runs while others it gives me the error. Seems to be at a random order. Also, the program never fails when I run it on gdb it always exits correctly. Why is this happening?

Your limits are reversed in your initialization code. You create your arrays like this:
this->_vertical = new simpleNode [rows]; // <== uses rows for sizing vertical
this->_horizontal = new simpleNode [cols]; // <== uses cols for sizing horizontal
But your initialization does this:
for (i=0; i<this->_rows; i++) // <== limit is rows, but you walking horizontal
this->_horizontal[i]._next = NULL;
for (i=0; i<this->_cols; i++) // <== limit is cols, but you walking vertical
this->_vertical[i]._next = NULL;
Unless rows and cols are the same value, this code invokes undefined behavior. Fix this by using the same values as you sized your allocation with
for (i=0; i<this->_rows; i++)
this->_vertical[i]._next = NULL;
for (i=0; i<this->_cols; i++)
this->_horizontal[i]._next = NULL;
Honestly a much better approach would use RAII containers such as std::vector<>, but I leave that as an exercise for you.
Best of luck, and hope it helps.

Since you're in the debugger, you should look at the memory location 0x7fff7a1d4300 and see what's there. The data in memory may be helpful in figuring out what's going wrong.
What's happening is one of the following:
you are freeing an object twice,
you are freeing a pointer that was never allocated
you are writing through an invalid pointer which previously pointed to an object which was already freed
I think what happens is No.3.
My answer is based in this answer.
A relevant discussion lies here.
Relevant question about gdb.

Related

How to Delete from a dynamic array

I am having issues with getting my MyDynamicArray class to delete the array. The delete[] a statement causes my program to spit out the error "Aborted (core dumped)" when I run it. What could be the problem?
private:
int size, capacity, error, *a;
public:
MyDynamicArray() {
capacity = 2;
size = 0;
a = new int[capacity];
}
void del() {
// half the capacity if the size is 1/4 of capcity
// make a new array and the free the last one
if (size <= (capacity / 4)) {
capacity = capacity / 2;
int* a2 = new int[capacity];
for (int i = 0; i < size; i++) {
a2[i] = a[i];
}
cout << "Reducing to : " << capacity << endl;
delete [] a;
}
size--;
}
From the given code, I couldn't figure out what you are trying to do. But some issues with the code as given below.
You didn't assign any address to 'a' (at least from the given code). You are trying to use it & delete it which will give unexpected results.
You are trying to use 'a' after deleting it.
You can read the doc
Using delete on a pointer to an object not allocated with new gives unpredictable results.
Also you assign value to array a after you try to delete it (your final loop)
Another big problem that I see and may cause the crash is that , in your first loop, you should loop until capacity and not size (assuming that capacity is inferior to size, and you need to implement a check on this to also avoid segfault).
If you want to clear array a of its values, you can use (void)a; but it will fill its value with 0.
What you want to do is in fact to fill a2 with value inside of a (that you did), and then change a to point to a2.

Incorrect checksum for freed object - error when printing

I have made a class that's supposed to make a symmetric toeplitz matrix (see here). The implementation of the class is shown here
class toeplitz{
private:
int size;
double* matrix;
public:
toeplitz(const double* array, const int dim){
size = dim;
matrix = new double(size*size);
for(int i = 0; i < size; i++){
for (int j = 0; j < size; j++){
int index = std::abs(i - j);
matrix[i*size + j] = array[index];
}
}
}
~toeplitz(){
delete[] matrix;
}
void print() const{
//loop over rows
for (int i = 0; i < size; i++){
//loop over colums
for (int j = 0; j < size; j++){
double out = matrix[i*size + j];
std::cout << std::setw(4) << out;
}
//start new line for each row
std::cout << "\n";
}
}
};
I can't see what's wrong with this, but when I try and use this in a simple test function, I get malloc errors. The main function I have is
int main(){
double array[] = {0,1,1,2};
int len = sizeof(array)/sizeof(array[0]);
std::cout<<"length of array " << len << std::endl;
toeplitz tp = toeplitz(array, len);
tp.print();
}
It compiles and runs when I leave out the tp.print() line, but when I add this line I get error
test_toeplitz(8747,0x7fffdbee63c0) malloc: *** error for object 0x7fb119402788:
incorrect checksum for
freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
I cannot figure out why this is. I've looked at the other questions about this on here but I can't tell how they relate to what I've done. As I understand it has to do with either double freeing memory or trying to modify memory after it's been freed, but I can't see where my code is doing that. Any insight into what's going on would be appreciated.
You stumbled on the classical:
matrix = new double(size*size);
which allocates a double worth size*size when you wanted to do:
matrix = new double[size*size];
to allocate an array of the proper size. So you get undefined behaviour. Sometimes it works sometimes not depending on the memory configuration.
Since you're using C++, I suggest you use std::vector<double> or Eigen matrix template, and drop C arrays forever (no more memory leaks, no more failed allocations, possible boundary checking, only advantages)

Dynamic Arrays: Need help copying one array to another one

I have to create a program that uses the 'new' operator to create a dynamic array in heap of the program. The program creates and populates its dynamic array one (int) elements at a time for each input data (cin).
Key parts.
1.) Program has to used "cin >>" for data input to accept on integer at a time until EOF is pressed on the keyboard (cntrl-z for windows).
2.) User input has to be tested using !cin.eof() && cin.good() to test whether or not the EOF key was pressed and if the data is valid. (kinda of confused about the cin.good() part).
3.) The program will create a series of longer and longer arrays to contain all previous elements and the current incoming one. Also, the program will delete the previous version of the array after completing the current version.
4.) The program also tests if heap memory has been exhausted after each use of the new operator. (need help with this)
I keep getting error message "HEAP CORRUPTION DETECTOR After normal black (#146)" (visual studio). What's the issue?
Thanks in advance!
Here's the code:
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <cassert>
using namespace std;
// main
int main() {
int size = 2;
int * array1 = new int[size];
int arrayInput;
int count = 0;
do {
if (array1 != NULL) {
cout << "Enter an integer (EOF to stop): " << endl;
cin >> arrayInput;
if (size < count) {
int * tempArray;
tempArray = new int[size * 2];
if (tempArray != NULL)
{
for (int i = 0; i < size; i++) {
array1[i] = tempArray[i];
}
delete[] array1;
array1 = tempArray;
size *= 2;
delete [] tempArray;
}
else
cout << "Insufficient Heap resource." << endl; // If we get here the Heap is out of space
}
if (!cin.eof()) {
array1[count++] = arrayInput;
}
}
else
cout << "Insufficient Heap resource." << endl; // If we get here the Heap is out of space
} while (!cin.eof());
for (int i = 0; i < count; i++) {
cout << array1[i] << endl;
}
}
tempArray = new int[size * 2];
if (tempArray != NULL)
{
for (int i = 0; i < size; i++) {
array1[i] = tempArray[i];
}
You allocate a new array twice as big as your old array. Then you copy the contents of the newly allocated array into your existing array. The newly-allocated array contains random garbage, that you just used to override the existing, good data, in your old array.
That's one obvious bug, but it won't explain the crash.
delete[] array1;
array1 = tempArray;
size *= 2;
delete [] tempArray;
After copying, you delete your old array. Then you also delete your new array, that you just allocated. That smells like another bug, but it still won't explain the crash.
if (!cin.eof()) {
array1[count++] = arrayInput;
}
Now, you can answer your own question here: what happens when you continue to write to a pointer that was pointing to memory that you freed, recently?
That are multiple bugs in the shown code. They all must be fixed. I haven't looked further, past this point. There might still be other issues with this code. A rubber duck should be able to help you to find any remaining bugs in your program.

Segmentation Fault C++

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.

Why do I get a segmentation fault (core dumped) when I try to allocate a 4D array?

I'm trying to allocate a large 4D matrix but I want to do it dynamically. When I just create the static matrix everything works fine so I know I have enough memory for now. However when I try and implement the same thing dynamically it breaks whenever I enter the third dimension and I need to get to a fourth! Can anyone tell me why this code does not work?
#include <iostream>
using namespace std;
static const int time1 = 7;
static const int tlat = 15;
static const int tlon = 17;
static const int outlev = 3;
int main(void)
{
//allocate four dimensional dataIn
int ****dataIn;
dataIn = new int ***[time1];
if (dataIn == NULL) { return 1; }
for(int i = 0 ; i < time1 ; i++) {
dataIn[i] = new int **[tlat];
if (dataIn[i] == NULL) { return 1; }
for(int j = 0 ; j < tlat ; j++) {
dataIn[i][j] = new int *[tlon];
if (dataIn[i][j] == NULL) { return 1; }
for(int k = 0 ; k < tlon ; k++) {
dataIn[i][j][k] = new int[outlev];
if (dataIn[i][j][k] == NULL) { return 1; }
}
}
}
//there is more code that happens here to add values to dataIn
//and eventually output it but I know all of that works
return 0;
}
I have tried many different variations on this code, and even used malloc instead of new, but I cannot get it working. Any help will be greatly appreciated.
Have you run this in a debugger? To my eyes the code looks fine, but a debugger will tell you where it's crashing which alone may be enough to help you fix it
You're probably best off allocating all the memory in a flat array and then calculating the indices yourself. Wrapping the whole thing in an object for encapsulation.
class Matrix {
private:
int* data;
int[] sizes;
int nDimensions;
public:
// allocates the data pointer and copies the other parameters
Matrix(int[] sizes, int nDimensions);
// frees the data and sizes arrays
~Matrix();
// calculates the cell position and returns it
int getCell(int[] coordinates);
// calcultes the cell position and sets its value
void setCell(int[] coordinates, int value);
private:
// used by getCell and setCell, calculates the cell's
// location in the data array
size_t calculateCellPosition(int[] coordinates);
};
It compiles and runs fine on my Linux machine.
BTW, with standard C++, new would throw a std::bad_alloc exception (instead of returning NULL) when it's unable to allocate the memory. So it might be worth catching that exception instead of testing for a NULL pointer.
As pointed out by cmeerw, testing against NULL or 0 is not needed in std-c++.
It would help if you could add a comment to the exact spot where you get a segv.
Also: Which compiler are you using and on which OS?
Check out boost::multiarray, it does exactly what you want, except more efficiently by only doing a single heap allocation.