Memory Allocation Problems with structure - c++

Why does the provided code crash at the following line?
data *fillA = (data*)calloc(matrixa->nzmax, sizeof(data));
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <algorithm>
#include <time.h>
using namespace std;
struct csr
{
int rows;
int cols;
int nzmax;
int *rowPtr;
int *colInd;
double *values;
};
struct data
{
int entry;
int index;
};
bool descend(const data &a, const data &b)
{
return a.entry > b.entry;
}
static bool ascend(const data &a, const data &b)
{
return a.entry < b.entry;
}
void csrtranspose(struct csr *matrixa)
{
int i, j, counter;
double *tArray = NULL;
data *fillA = (data*)calloc(matrixa->nzmax, sizeof(data));//fails here
for (int i = 0; i < matrixa->nzmax; i++)
{
fillA[i].entry = matrixa->colInd[i];
fillA[i].index = i;
}
sort(fillA, fillA + matrixa->nzmax, ascend);
tArray = (double*)calloc(matrixa->nzmax, sizeof(double));
for (int i = 0; i < matrixa->nzmax; i++)
{
tArray[i] = matrixa->values[i];
}
for (int i = 0; i < matrixa->nzmax; i++)
{
matrixa->colInd[i] = fillA[i].entry;
matrixa->values[i] = tArray[fillA[i].index];
}
free(tArray);
free(fillA);
}
int main()
{
int i;
struct data *total = 0;
struct csr *s = 0;
int nrows = 6, ncols = 5, counter = 0, nzmax = 10, rows = 3, cols = 5;
double values[10] = {0.2135, 0.8648, 7, 0.3446, 0.1429, 6, 0.02311, 0.3599, 0.0866, 8 };
int rowPtr[4] = { 0, 3, 6, 10 };
int colInd[10] = { 0, 2, 4, 1, 2, 3, 0, 1, 2, 4 };
s = (struct csr*) calloc(1, sizeof(struct csr));
s->rows = rows;
s->cols = cols;
s->nzmax = nzmax;
s->rowPtr = (int*)calloc(s->rows + 1, sizeof(int));
s->colInd = (int*)calloc(s->nzmax, sizeof(int));
s->values = (double*)calloc(s->nzmax, sizeof(int));
for (i = 0; i<10; i++)
{
s->colInd[i] = colInd[i];
s->values[i] = values[i];
if (i <= s->rows)
{
s->rowPtr[i] = rowPtr[i];
}
}
csrtranspose(s);
getchar();
}

The reason why it crashes there is because memory has already been corrupted by previously faulty code. So, the problem is not there where it crashes, the problem is in code which executed earlier.
Specifically, this line:
s->values = (double*)calloc(s->nzmax, sizeof(int));
Allocates doubles, but uses sizeof(int), so it does not allocate enough memory.
EDIT
Recommendations:
As others have already pointed out, when working with C++, use the new operator instead of C-style memory allocation. It will save you from LOTS of problems.
If you insist on using C-style allocation, never use p = (type*)malloc( sizeof(type) ), always use p = (type*)malloc( sizeof( *p ) ). This will at least make it more evident when you make the very common mistake of allocating memory for the wrong type.

The line (double*)calloc(s->nzmax, sizeof(int)); in itself is a good reason to switch to C++ allocation, where it's impossible to make that mistake even if you copy-and-paste.
You're allocating too little memory and writing out of bounds.
Since all your sizes are known at compile time, you don't really need dynamic allocation at all.

Related

C++: Using dynamic memory allocation to write a function similar to the C realloc() function (i.e. change it's size)

I would like to write a function (changeSize) that uses DMA, where I can choose to change it's (an array's) size to whatever I want, where oldEls is the original size, and newEls is the new size. If newEls is larger than oldEls, I would just add zero's to the end, and if it is smaller than oldEls, I would just truncate. The "ptr" parameter needs to point to the new array. It is my understanding that this would be similar to the C realloc() function.
With the code presently below, I am outputting the following: 0, 0, 3, 6, 0, 0, 0, 0, where the correct output should be 4, 2, 3, 6, 0, 0, 0, 0. I also realize that my show function is maybe not the best function to output the new array, since I have to explicit state the array element size.
Thanks in advance.
#include <iostream>
#include <cstdlib>
using namespace std;
void show( const int a[], unsigned elements );
int * copy( const int a[], unsigned els );
void changeSize( int * & ptr, int newEls, int oldEls );
void die(const string & msg);
int main()
{
int arr[4] = {4, 2, 3, 6};
show(arr, 4);
int * newArr = copy(arr, 4);
cout << endl << endl;
changeSize(newArr, 8, 4);
show(newArr, 8);
}
void show( const int a[], unsigned elements )
{
for (int i = 0; i < elements; i++)
cout << a[i] << endl;
}
int * copy( const int a[], unsigned els )
{
int *newArr;
try
{
newArr = new int[els];
}
catch(const bad_alloc &)
{
die("Copy: Alloc Failure");
}
for (int i = 0; i < els; i++)
newArr[i] = a[i];
return newArr;
}
void changeSize( int * & ptr, int newEls, int oldEls )
{
int * newArr;
try
{
newArr = new int[newEls];
for (int i = 0; i < oldEls; i++)
{
newArr[i] = ptr[i];
}
if (newEls > oldEls)
{
for (int k = oldEls; k < newEls; k++)
newArr[k] = 0;
}
}
catch(const bad_alloc &)
{
die("changeSize: Alloc Failure");
}
ptr = newArr;
delete[] newArr;
}
void die(const string & msg)
{
cerr << "Fatal error: " << msg << endl;
exit(EXIT_FAILURE);
}
First of, you call delete on newArr at the end of changeSize. you need to delete the old value of ptr (that you currently discard). That's (probably) the problem
While I'm at it, I'd like to point your interest to std::vector. It's basically a resizeable array.
Also, copying raw chucks of memory is still best done with memcpy, don't waste your time with writing for loops just to copy ints, do that only for C++ classes.
EDIT: using std::copy is the best solution for C++, it uses memcpy when it can, otherwise it's the same as a for loop copying the objects.
Cheers!

Segmentation Fault in Linux C++ but code is working in windows

AoA,
Here is the code of multiplication of two matrices, which runs fine under 3x3 matrices but gives error on exceding row or column of 3x3, like on 3x4 and 4x3 it gives the error "segmentation fault"
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
struct matrix
{
int** mat;
int row;
int col;
matrix(int m,int n)
{
row = m;
col = n;
mat = new int*[row];
for( int i=0;i<row;i++ )
{
mat[i] = new int[col];
for( int k=0;k<col;k++ )
{
mat[i][k] = 0;
}
}
}
};
matrix* MultiplyMat(matrix* matA,matrix* matB)
{
matrix* tMat = new matrix(matA->row,matB->col);
if(matA->row == matB->col)
{
for( int i=0; i<matA->row; i++ )
{
for( int j=0;j<matB->col;j++ )
{
for( int m=0;m<matB->col;m++ )
{
tMat->mat[j][i] += matA->mat[j][m] * matB->mat[m][i];
}
}
}
}
return tMat;
}
void PrintMatrix(matrix* tMat)
{
cout<<"Print: Matrix\n\n";
for( int i=0;tMat->row;i++ )
{
for( int j=0;j<tMat->col;j++ )
{
cout<<" "<<tMat->mat[i][j];
}
cout<<"\n";
}
}
int main()
{
matrix matB(3,4);
matrix matA(4,3);
matA.mat[0][0] = 2;
matA.mat[0][1] = 1;
matA.mat[0][2] = 4;
matA.mat[1][0] = 6;
matA.mat[1][1] = 5;
matA.mat[1][2] = 9;
matA.mat[2][0] = 8;
matA.mat[2][1] = 7;
matA.mat[2][2] = 11;
matA.mat[3][0] = 5;
matA.mat[3][1] = 5;
matA.mat[3][2] = 9;
matB.mat[0][0] = 2;
matB.mat[0][1] = 1;
matB.mat[0][2] = 4;
matB.mat[0][3] = 3;
matB.mat[1][0] = 6;
matB.mat[1][1] = 5;
matB.mat[1][2] = 9;
matB.mat[1][3] = 12;
matB.mat[2][0] = 8;
matB.mat[2][1] = 7;
matB.mat[2][2] = 11;
matB.mat[2][3] = 13;
matrix* matC = MultiplyMat(&matA,&matB);
PrintMatrix(matC);
return 0;
}
I am just trying to multiplay two matrices, the g++ compiler gives error "segmentation fault" I have tried debuging method(found on this site) but failed to remove the error!
Any help?
This line is wrong:
matrix* tMat = (matrix*)malloc(sizeof(matrix));
I'm not entirely sure what you are expecting this to do, but it probably doesn't do that... In fact, it doesn't do much at all, other than create a block of memory large enough for a the struct matrix. It is filled with some random garbage (which may or may not be zeros).
You then go on and use it:
tMat->mat[j][i] += matA->mat[j][m] * matB->mat[m][i];
which most likely means you are either accessing NULL or some random garbage address that isn't valid. You then return the pointer to it, which is not freed here:
matrix* matC = MultiplyMat(&matA,&matB);
PrintMatrix(matC);
return 0;
You probably want something like:
matrix* tMat = new matrix(matB->col, matA->row);
But you would be much better off creating a matrix operator*(const matrix& a, const matrix& b), so you don't return a pointer at all. The overhead will be pretty small.
Your matrix actually has a constructor but it isn't called when allocation memory using malloc(). You clearly want to use
matrix* tMat = new matrix(m, n);
with suitable argument m and n. Well, actually, you rather want to use
std::unique_ptr<matrix> tMat(new matrix(m, n));
... but this is just related to the next problem you'll get once you get past your segmentation fault: you also need to clean up resources. It is also not quite what your really want, though, because you really want something like this:
matrix MultiplyMat(matrix const& a, matrix const& b) {
// ...
matrix result(m, n);
// ...
return result;
}

Every n element of an array in C++

Are there more efficient methods of getting every second (every N in general) element of an array then the simple for loop below? For example with the use of generic algorithms?
#include<iostream>
using namespace std;
int main()
{
const int a_size = 6, b_size = 3;
int a[a_size] = {1, 3, 6, 3, 2, 7};
int b[b_size];
int bx = 0;
for ( int ax = 0; ax < a_size; ++ax )
{
if (ax % 2 == 0)
b[bx++] = a[ax];
}
}
for (int ax = 0; ax < a_size; ax += 2)
Just be careful if a_size is close to INT_MAX.
A loop should be good enough. As Pete pointed out, you can avoid the modulo test.
for (int ax = 0; ax < a_size; ax += 2)
...
C++ offers support for slicing via the valarray header (e.g., take a look at std::slice_array).
I don't know if that is what you are looking for. It is intended for heavyweight numeric computations. If you are unsure, I think the simple loop is the right answer.
If by efficient, you mean faster with a smaller memory footprint, then I would opt to use pointers instead of array access. For example, what you want can be implemented in the following way with pointers.
int main() {
const int a_size = 6, b_size = 3;
int a[a_size] = {1, 3, 6, 3, 2, 7};
int b[b_size];
int* a_ptr = a;
int* a_end_ptr = a_ptr + a_size;
int* b_ptr = b;
while(a_ptr < a_end_ptr) {
*b_ptr = *a_ptr;
b_ptr++;
a_ptr += 2;
}
}
This example should be slightly faster than the array access examples and I encourage you to time it and see for yourself. However one thing you should always be aware of when making these optimizations is to look at whether it matters in the large scheme of the program (don't spend time when you don't have to).
You could easily create a every_n predicate and use that to filter as desired for copy_if, etc. That's as generic as you can get.
Approximate (note: untested as of yet) example of an "every n elements" predicate:
/**
#brief Un predicado que retorna #c true cada #a n invocaciones.
**/
template <typename Integer>
struct every_n {
static_assert (std::numeric_limits<Integer>::is_integer, "Must behave like an integer");
public:
explicit every_n (Integer const& e)
: n(e), x(1) {}
every_n (every_n const& E)
: n(E.n), x(E.x) {}
bool operator () (...) {
if (x<n) { ++x; return false; }
else { x=Integer(1); return true; }
}
private:
Integer x;
const Integer n;
};
// "make_" idiom
template <typename Integer>
every_n<Integer> every (Integer const& c) { return every_n<Integer>(c); }
// sample usage
# include required headers, etc
using namespace std;
const int a_size = 6, b_size = 3;
int a[a_size] = {1, 3, 6, 3, 2, 7};
int b[b_size];
copy_if (begin(a), end(a), begin(b), every(3));
All the code requires is that every() is called with a type that behaves like an integer.
(The code uses static_assert, begin(), end() and copy_if(), which are C++11, but functions just as well in C++03 if you backport the adequate functions, as I have)
This is as fast as it gets:
void copy_n(int & a[], int & b[], int a_sz, int n) {
int bx = 0;
for (int i=0; i<a_sz; i+=n) {
b[bx++]=a[i];
}
}
Example:
#include<iostream>
using namespace std;
int main() {
const int a_size = 6;
const int b_size = a_size / 2;
int a[a_size] = {1, 3, 6, 3, 2, 7};
int b[b_size];
for (int ax = 0, bx = 0; ax < a_size; ax += 2) {
b[bx++] = a[ax];
}
}

sigsegv error in aggregate method

Here is my code:
#include <cstdlib>
#include <stdio.h>
#define NUM_READINGS 3
int* readingsTotal;
int* readingsAverage;
int readingsIndex;
using namespace std;
void avgOf(int* toFindAvgOf, int size) {
int i;
for (i = 0; i < size; i++) {
// Add reading to total for each component.
readingsTotal[i] += toFindAvgOf[i];
// Once method has been iterated through n (NUM_READINGS) times:
if (readingsIndex == NUM_READINGS - 1) {
// Set the arithmetic mean.
readingsAverage[i] = readingsTotal[i] / NUM_READINGS;
// Reset the total.
readingsTotal[i] = 0;
}
}
readingsIndex++;
}
int iterate(int findAvgOf) {
int toFindAvgOf[] = {findAvgOf, 20, 30};
avgOf(toFindAvgOf, sizeof (toFindAvgOf));
return readingsAverage[0];
}
int main(int argc, char** argv) {
readingsTotal = (int []){0, 0, 0};
readingsAverage = (int []){0, 0, 0};
int i;
for (i = 0; i < 3; i++) {
int smthd = iterate(12 + i * 2);
printf("%d\n", smthd);
}
return 0;
}
When I run this in netbeans c/c++, it builds with now errors but when it executes it fails and prints:
RUN FAILED (exit value 1, total time: 86ms)
When I go into debug mode it also fails immediately and gives the SIGSEGV error. From reading online I'm guessing there is some issue with the way I am dereferencing a pointer. But I have no clue where exactly it is failing at. I am pretty new to c++ so any help would be great!
In C, the sizeof function returns the size of the object in bytes.
So when you say:
sizeof (toFindAvgOf)
That will return 12 (assuming an int on your system is 4-bytes) thus causing an index out of bounds condition in the avgOf function.
To get the length of the array:
sizeof(toFindAvgOf) / sizeof(int)

How to declare an array of pointers to int arrays?

I am trying to declare an array of pointers each of which points to int arrays of different sizes. Any ideas?
From your description it sounds like you are looking for a pointer to a pointer.
int **aofa;
aofa = malloc(sizeof(int*) * NUM_ARRAYS);
for (int i = 0 ; i != NUM_ARRAYS ; i++) {
aofa[i] = malloc(sizeof(int) * getNumItemsInArray(i));
}
for (int i = 0 ; i != NUM_ARRAYS ; i++) {
for (int j = 0 ; j != getNumItemsInArray(i) ; j++) {
aofa[i][j] = i + j;
}
}
NUM_ARRAYS arrays may have different number of elements, as determined by the value returned by the getNumItemsInArray(i) function.
int* ar[2];
int ar1[] = {1,2, 3};
int ar2[] = {5, 6, 7, 8, 9, 10};
ar[0] = ar1;
ar[1] = ar2;
cout << ar[1][2];
C version, should help clarifying the different types of declarations:
#include <stdio.h>
int main()
{
/* let's make the arrays first */
int array_A[3] = {1, 2, 3};
int array_B[3] = {4, 5, 6};
int array_C[3] = {7, 8, 9};
/* now let's declare some pointers to such arrays: */
int (*pA)[3] = &array_A;
int (*pB)[3] = &array_B;
int (*pC)[3] = &array_C; /* notice the difference: */
/* int *pA[3] would be an array of 3 pointers to int because the [] operator*/
/* has a higher precedence than *(pointer) operator. so the statement would */
/* read: array_of_3 elements of type_pointer_to_int */
/* BUT, "int (*pA)[3]" is read: pointer_A (points to) type_array_of_3_ints! */
/* so now we need a different array to hold these pointers: */
/* this is called an_ARRAY_of_3_pointers to_type_array_of_3_ints */
int (*ARRAY[3])[3] = {pA, pB, pC};
/* along with a a double pointer to type_array_of_3_ints: */
int (**PTR)[3] = ARRAY;
/* and check that PTR now points to the first element of ARRAY: */
if (*PTR == pA) printf("PTR points to the first pointer from ARRAY \n");
PTR++;
if (*PTR == pB) printf("PTR points to the second pointer from ARRAY! YAY!\n");
return 0;
}
> $ clang prog.c -Wall -Wextra -std=gnu89 "-ansi" output:
> PTR points to the first pointer from ARRAY
> PTR points to the second pointer from ARRAY! YAY!
Check out the section "Pointers to Arrays of Objects"
http://www.functionx.com/cpp/Lesson24.htm
It might help you.
In C++ you can declare it like shown below.new operator can work like similar to malloc in C.
int** array = new int*[n];
#include <iostream>
using namespace std;
#define arraySize 3
const int arr1[] = {48,49,50};
const int arr2[] = {64,65,66};
const int arr3[] = {67,68,69};
typedef const int (*arrayByte);
arrayByte arrayPointer[arraySize] = {
arr1,arr2,arr3
};
void printArr(const int arr[], int size){
for(uint8_t x=0;x<size;x++){
printf("value%d=%d \n",x,arr[x]);
}
}
int main()
{
printf("Print Array 0\n");
printArr(arrayPointer[0],arraySize);
printf("Print Array 1\n");
printArr(arrayPointer[1],arraySize);
printf("Print Array 2\n");
printArr(arrayPointer[2],arraySize);
return 0;
}
try this code: C++ online