Segfault after refactoring nested loops - arrays

I have some MATLAB code from a digital audio course that I've ported to C. Given an array of numeric data (for example, PCM audio encoded as double-precision floating-point), produce an array of data segments of a specified width and which overlap each other by a specified amount. Here's the relevant code.
typedef struct AudioFramesDouble {
const size_t n, // number of elements in each frame
num_frames;
double* frames[];
} AudioFramesDouble;
/*
* Produce a doubly-indexed array of overlapping substrings (a.k.a windows, frames,
* segments ...) from a given array of data.
*
* x: array of (i.e., pointer to) data
* sz: number of data elements to consider
* n: number of elements in each frame
* overlap: each frame overlaps the next by a factor of 1 - 1/overlap.
*/
AudioFramesDouble* audio_frames_double(register const double x[], const size_t sz, const unsigned n, const unsigned overlap) {
// Graceful exit on nullptr
if (!x) return (void*) x;
const double hop_d = ((double) n) / ((double) overlap); // Lets us "hop" to the start of the next frame.
const unsigned hop = (unsigned) ceil(hop_d);
const unsigned remainder = (unsigned) sz % hop;
const double num_frames_d = ((double) sz) / hop_d;
const size_t num_frames = (size_t) (remainder == 0
? floor(num_frames_d) // paranoia about floating point errors
: ceil(num_frames_d)); // room for zero-padding
const size_t total_samples = (size_t) n * num_frames;
AudioFramesDouble af = {.n = n, .num_frames = num_frames};
// We want afp->frames to appear as (double*)[num_frames].
AudioFramesDouble* afp = malloc((sizeof *afp) + (sizeof (double*) * num_frames));
if (!afp) return afp;
memcpy(afp, &af, sizeof af);
for (size_t i = 0; i < num_frames; ++i) {
/* Allocate zero-initialized space at the start of each frame. If this
fails, free up the memory and vomit a null pointer. */
afp->frames[i] = calloc(n, sizeof(double));
if (!afp->frames[i]) {
double* p = afp->frames[i];
for (long ii = ((long)i) - 1; 0 <= ii; ii--) {
free(afp->frames[--i]);
}
free(afp);
return (void*) p;
}
for (size_t j = 0, k; j < n; ++j) {
if (sz <= (k = (i*hop) + j)) break;
afp->frames[i][j] = x[k];
}
}
return afp;
}
This performs as expected. I wanted to optimize the nested FOR to the following
for (size_t i = 0, j = 0, k; i < num_frames; (j == n - 1) ? (j = 0,i++) : ++j) {
// If we've reached the end of the frame, reset j to zero.
// Then allocate the next frame and check for null.
if (j == 0 && !!(afp->frames[i] = calloc(n, sizeof(double)))) {
double* p = afp->frames[i];
for (long ii = ((long)i) - 1; 0 <= ii; ii--) {
free(afp->frames[--i]);
}
free(afp);
return (void*) p;
}
if (sz <= (k = (i*hop) + j)) break;
afp->frames[i][j] = x[k];
}
This actually compiles and runs just fine; but in my testing, when I try to access the last frame as in
xFrames->frames[xFrames->num_frames-1],
I get a segmentation fault. What's going on here? Am I neglecting an edge case in my loop? I've been looking over the code for awhile, but I might need a second set of eyes. Sorry if the answer is glaringly obvious; I'm a bit of a C novice.
P.S. I'm a fan of branchless programming, so if anyone has tips for cutting out those IFs, I'm all ears. I was using ternary operators before, but reverted to IFs for readability in debugging.

Remember that the logical operator && and || does short-circuit evaluation.
That means if j != 0 then you won't actually call calloc, and you'll have an invalid pointer in afp->frames[i].

Related

C Keep Getting Double Free, despite trying to free in same form as allocation

Hey I'm trying to do a simple machine learning application for school but I keep getting double free for some reason I cannot even fathom.
float * evaluate(Network net,float * in)
{
int i,j;
float * out;
Neuron cur_neu;
for(i=0,j=0;i<net.n_lay;i++) j = net.lay_sizes[i]>j?net.lay_sizes[i]:j; //Calculating the maximum lay size for output storage
out = (float *) malloc(j*sizeof(float));
for(i=0;i<net.n_lay;i++) //Cycling through layers
{
for(j=0;j<net.lay_sizes[i];j++) //Cycling through Neurons
{
cur_neu=net.matrix[i][j];
out[j] = cur_neu.af(cur_neu.w,in,net.lay_sizes[i-1]); //Storing each answer in out
}
for(j=0;j<net.lay_sizes[i];j++) in[j] = out[j]; //Transfering answers to in
}
return out;
}
float loss(Network net, float **ins_orig, int t_steps)
{
float **profecies;
float st = .5f;
int d_steps = 4;
int t, i, j;
int out_size = net.lay_sizes[net.n_lay - 1];
int in_size = net.lay_sizes[0];
float out = 0.0f;
float **ins;
/*
d_steps = Divination Steps: Number of time steps forward the network has to predict.
The size of the output layer must be d_steps*#ins (deconsidering any conceptual i/os)
t_steps = Total of Steps: Total number of time steps to simulate.
*/
//Copying ins
ins = (float **)malloc(t_steps * sizeof(float *));
for (i = 0; i < t_steps; i++) //I allocate memory for and copy ins_orig to ins here
{
ins[i] = (float *)malloc(in_size * sizeof(float));
for (j = 0; j < in_size; j++)
ins[i][j] = ins_orig[i][j];
}
//
profecies = (float **)malloc(t_steps * sizeof(float *));
for (t = 0; t < t_steps; t++)
{
profecies[t] = evaluate(net, ins[t]);
/*
Profecy 0:
[[a1,b1,c1,d1]
[e1,f1,g1,h1]
[i1,j1,k1,l1]]
Profecy 1:
[[e2,f2,g2,h2]
[i2,j2,k2,l2]
[m2,n2,o2,q2]]
Verification for:
t=0:
loss+= abs(a1-ins[t][0]+b2-ins[t][1]...)
t=1:
t=0:
loss+= abs(e1-ins[t][0]+f2-ins[t][1]...)
*/
for (i = 0; i < d_steps; i++) //i is distance of prediction
{
if (i <= t) // stops negative profecy indexing
{
for (j = 0; j < in_size; j++)
{
out += (ins[t][j] - profecies[t-i][j+in_size*i]) * (ins[t][j] - profecies[t-i][j+in_size*i]) * (1 + st*i); //(1+st*i) The further the prediction, the bigger reward
}
}
}
}
//Free ins
for (i = 0; i < t_steps; i++) //I try to free it here, but to no avail
{
free(ins[i]);
}
free(ins);
return out;
}
I realize it's probably something very obvious but, I can't figure it out for the life of me and would appreciate the help.
Extra details that probably aren't necessary:
evaluate just passes the input to the network (stored in ins) and returns the output
both inputs and outputs are stored in float "matrixes"
Edit: Added evaluate
In your loss() you allocate the same number of floats for each ins:
ins[i] = (float *)malloc(in_size * sizeof(float));
In your evaluate() you calculate the longest lay_size, indicating that it may NOT be net.lay_sizes[0]:
for(i=0,j=0;i<net.n_lay;i++) j = net.lay_sizes[i]>j?net.lay_sizes[i]:j; //Calculating the maximum lay size for output storage
Then you are writing out-of-bounds here:
for(j=0;j<net.lay_sizes[i];j++) in[j] = out[j]; //Transfering answers to in
From that point, your memory is corrupted.

Why is the pointer to pointer arithmatic failing in my conditional statment?

sm is a 2D array of character pointers allocated dynamically. I need to understand why my pointer to pointer arithmetic is failing in conditional if in loop structure.
2nd column in sm is where the string is that I need to test with the grade key gk which is array of characters/string. s holds row size and q is column size for 2D array, hm is my heap memory counter for freeing function which is not importing for my question.
double *cals(char **sm, char *gk, int s, int q, unsigned *hm) {
int c = 0;
double *savg = malloc(s * sizeof(double));
assert(savg);
*hm += 1;
for (int i = 0; i < s; *(savg + i) = c / q * 100 , c = 0, ++i) {
for (int j = 0; j < q; ++j) {
if (*(*(sm + i * STUDENTATT + 1) + j) == *(gk + j))
++c;
}
}
return savg;
}
There isn't much information given about the purpose of cals function so I had to make a few assumptions to write this answer.
Assumption-1(meaningful):-
You want to find how much characters in the two strings are equal(no every characters) and then find the percentage of the same characters to the total characters. If that is the case use the below code.
double *cals(char **sm, char *gk, int s, int q, unsigned *hm) {
float c = 0; // To force float division the c is declared as a float variable
double *savg = malloc(s * sizeof(double));
assert(savg);
*hm += 1;
char* sm_i_key = NULL;
unsigned int strlen_gk = strlen(gk);
unsigned int key_length = string_gk;
for (int i=0; i<s; ++i) { //The calculation is moved inside for loop
sm_i_key = *(sm+i*q+1); // You can also use sm_i_key = &sm[i*q+1]
/* Uncomment this section if length of 2 strings are not bound to be equal
if(strlen(sm_i_key) < strlen_gk){
key_length = sm_i_key;
}
else{
key_length = strlen_gk
}
*/
for (int j = 0; j < key_length; ++j) {
if (sm_i_key[j] == gk[j])
++c;
}
savg [i] = c / strlen_gk * 100; /* Since gk is the grade key it is assumed
to be equal to the total number.*/
c = 0;
}
return savg;
}
Assumption-2:-
You want to check whether the strings whose starting address is stored in the second column of each row of a 2D array sm is equal to the string stored in array pointed by gk and then calculate a value(double).
The function cals only returns 0.0 or 100.0 as the formula avgs[i]=c / q * 100 will only produce 0 if stings are not equal(since integer division c/q will always result in 0 if c is less than q which is the case here) and 100 if strings are equal(Then why use a double to store the value if only 0 and 100 is stored).
If that is the case then what you are doing here is fine unless the array gk and array sm[i][2] have different string length(not q). It would be better to use strncmp to check the equality of string if the string length of two array's are bound to be different.
Use the below code to do that:-
double *cals(char **sm, char *gk, int s, int q, unsigned *hm) {
int c;
char* sm_i_key = NULL;
double *savg = malloc(s * sizeof(double));
assert(savg);
*hm += 1;
for (int i=0; i < s;++i){//The calculation is moved to a static assignment given below
if(strncmp(sm_i_key, gk, strlen(gk) == 0)
{
savg[i] = 100.0; // Since c/q * 100 => 100.0 if q == c
}
else
{
savg[i] = 0.0; /*Since c/q *100 => 0.0 if q < c since integer
division will result in 0.*/
}
}
return savg;
}
I hope it helps.

How to work on a sub-matrix in a matrix by pointer?

I have a matrix of size n. Take an example:
My recursive function does the processing on the elements that lie in the border of the matrix. Now I want to call it (the recursive call) on the inner square matrix:
This is the prototype of my recursive function:
void rotate(int** mat, size_t n);
I know that a 2D array is an array within an array. I know that *(mat+1) + 1) will give the memory address that should be the base address of my new matrix. This is what I tried:
rotate((int **)(*(mat+1) + 1), n-2)
But it does not work, and I get a segfault when I try to access it with [][].
You cannot dereference mat+1 and reinterpret that as a pointer to a whole matrix. Instead provide the offsets as arguments to your function (I assume n-by-n square matrices):
void rotate(int** mat, size_t i, size_t j, size_t n) {
// assuming row-wise storage
int *row0 = mat[j]; // assumes j < n
int *row1 = mat[j + 1]; // assumes j + 1 < n
// access row0[i..] and row1[i..]
}
If you had continuous storage for your matrix, you could do the following instead:
rotate(int* mat, size_t i, size_t j, size_t n) {
int atIJ = mat[j * n + i]; // assuming row-wise storage
// ...
}
I am not sure of your application, but I wonder if using #define for your matrix size would help....
#define X_SIZE 4
#define Y_SIZE 4
or even
#define N_SIZE 4
... because then you can use X_SIZE and Y_SIZE (OR N_SIZE) in your function without having to pass them explicitly.
in main you might put
int matrix[X_SIZE * Y_SIZE];
or
int matrix2[N_SIZE * N_SIZE];
then you can call the ith row and jth column element with
*(pmatrix + X_SIZE*j + i)
or
matrix[X_SIZE*j + i]
or
*(pmatrix2 + N_SIZE*j + i)
or
matrix2[N_SIZE*j + i]
where pmatrix and pmatrix2 are pointers to matrix and matrix2.
I am pretty sure there is no clever trick to be able to easily pass the inner square 2x2 matrix to a function, unless you were to copy the elements from the centre of your matrix into a new matrix and then copy back the result afterwards.
This is not an answer to the stated question, but it is an answer to the underlying problem: management of matrices and views to matrices with minimal effort.
This will garner downvotes, but it has been so useful in solving the underlying problems whenever the type of question the OP poses has been asked, I find it is worth showing this alternative approach here.
It is not interesting for small, fixed-size matrices, as the features only show their benefits when the sizes are larger or vary.
I use the following two structures to describe matrices. I shall leave out memory pool support (which allows one to manage a set of matrices as a pool, releasing them all at once, without having to manage each matrix separately) and everything related to multithreaded operation and thread-safety, for simplicity.
The code might contain typos; if you notice any, please leave a comment, and I'll fix them.
typedef int data_t; /* Matrix element data type */
struct owner {
long refcount; /* Number of referenced to this data */
size_t size; /* Number of elements in data[] */
data_t data[]; /* C99 flexible array member */
};
typedef struct {
int rows; /* Number of rows in this matrix */
int cols; /* Number of columns in this matrix */
long rowstride;
long colstride;
data_t *origin; /* Pointer to element at row 0, col 0 */
struct owner *owner; /* Owner structure origin points to */
} matrix;
#define MATRIX_INIT { 0, 0, 0L, 0L, NULL, NULL }
Matrix m element at row r, column c, is m.origin[r * m.rowstride + c * m.colstride], assuming 0 <= r && r < m.rows and 0 <= c < m.cols.
Matrices are typically declared as local variables, not as pointers. You do need to remember to free each individual matrix after you no longer need it. (The pool mechanism I omitted lets you avoid this, as all matrices in a pool are freed at once.)
Each matrix refers to exactly one owner structure. Owner structures record the number of references (the number of matrices referring to data in that structure), and are released when the reference count drops to zero:
void matrix_free(matrix *const m)
{
if (m != NULL) {
if (m->owner != NULL && --(m->owner.refcount) < 1L) {
m->owner.size = 0;
free(m->owner);
}
m->rows = 0;
m->cols = 0;
m->rowstride = 0L;
m->colstride = 0L;
m->origin = NULL;
m->owner = NULL;
}
}
Whenever a new matrix is created, the corresponding owner structure is created:
int matrix_new(matrix *const m, const int rows, const int cols)
{
const size_t size = (size_t)rows * (size_t)cols;
struct owner *o;
if (m == NULL)
return errno = EINVAL;
m->rows = 0;
m->cols = 0;
m->rowstride = 0L;
m->colstride = 0L;
m->origin = NULL;
m->owner = NULL;
if (rows < 1 || cols < 1)
return errno = EINVAL;
o = malloc(sizeof (struct owner) + size * sizeof (data_t));
if (o == NULL) {
return errno = ENOMEM;
o->refcount = 1L;
o->size = size;
m->rows = rows;
m->cols = cols;
m->origin = o->data;
m->owner = o;
#if DEFAULT_COLUMN_MAJOR > 0
/* Default to column-major element order */
m->rowstride = 1L;
m->colstride = (long)rows;
#else
/* Default to row-major element order */
m->rowstride = (long)cols;
m->colstride = 1L;
#endif
return m;
}
Note that the above does not initialize the matrix elements to any value, so they initially contain garbage.
Matrix transpose is a trivial, fast operation:
void matrix_transpose(matrix *const m)
{
if (m->rows > 0 && m->cols > 0) {
const int rows = m->rows;
const int cols = m->cols;
const long rowstride = m->rowstride;
const long colstride = m->colstride;
m->rows = cols;
m->cols = rows;
m->rowstride = colstride;
m->colstride = rowstride;
}
}
Similarly, you can rotate and mirror matrices, just remember to modify the origin member in those cases, too.
The interesting and useful cases are being able to create "views" into other matrices. The data referenced is exactly the same -- modifying one is immediately visible in the other(s); this is true aliasing --, no memory copying is needed. Unlike in most libraries (such as GSL, GNU Scientific Library), these "views" are perfectly ordinary matrices themselves. Here are some examples:
int matrix_submatrix_from(matrix *const m, const matrix *const src,
const int firstrow, const int firstcol,
const int rows, const int cols)
{
if (m == NULL || m == src)
return errno = EINVAL;
m->rows = 0;
m->cols = 0;
m->rowstride = 0L;
m->colstride = 0L;
m->origin = NULL;
m->owner = NULL;
if (firstrow + rows > src->rows ||
firstcol + cols > src->cols)
return errno = EINVAL;
if (src == NULL || src->owner == NULL)
return errno = EINVAL;
if (src->owner.refcount < 1L || src->owner.size == 0)
return errno = EINVAL;
else {
++(src->owner.refcount);
m->owner = src->owner;
}
m->origin = src->origin + src->rowstride * firstrow
+ src->colstride * firstcol;
m->rows = rows;
m->cols = cols;
m->rowstride = src->rowstride;
m->colstride = src->colstride;
return 0;
}
int matrix_transposed_from(matrix *const m, const matrix *const src)
{
if (m == NULL || m == src)
return errno = EINVAL;
m->rows = 0;
m->cols = 0;
m->rowstride = 0L;
m->colstride = 0L;
m->origin = NULL;
m->owner = NULL;
if (src == NULL || src->owner == NULL)
return errno = EINVAL;
if (src->owner.refcount < 1L || src->owner.size == 0)
return errno = EINVAL;
else {
++(src->owner.refcount);
m->owner = src->owner;
}
m->origin = src->origin;
m->rows = src->cols;
m->cols = src->rows;
m->rowstride = src->colstride;
m->colstride = src->rowstride;
return 0;
}
Using code similar to above, you can create one-row or one-column matrix views describing any row, column, or diagonal. (The diagonals are especially useful in certain situations.)
Submatrices can be mirrored or rotated, and so on.
You can safely free a matrix you only need a submatrix or other view from, as the owner structure reference count keeps track of when the data can be safely discarded.
Matrix multiplication, and other similar complex operations for larger matrices, are very sensitive to cache locality issues. This means that you are better off copying the source matrix data into compact arrays (with the arrays properly aligned and in elements in correct order for that operand). The overhead caused by both row and column having a separate stride (instead of only one, as is typical) is actually minimal; in my own tests, neglible.
The best feature of this approach, however, is that it lets you write efficient code without worrying about what is a "real" matrix, what is a "view", and how the actual underlying data is stored in an array, unless you care.
Finally, it is simple enough for anyone who grasps basic dynamic memory management in C to completely understand.

reallocating size of array gives me no change

I'm trying to realloc the size of my array but it doesn't change. I can separate it to two issues:
Coordinate *closeCoordinatesArray = malloc(sizeof(Coordinate) * 0);
Coordinate nextCoordinate = coordinatesMainArray[nextCoordinateIndex];
for (int p = 0; p < 4; p++) {
switch (p) {
case 0:
if (((nextCoordinate.x - 1) >= 0) && ((nextCoordinate.y - 1) >= 0)) {
int sizeOfArray = sizeof(*closeCoordinatesArray);
int sizeOfFirstObject = sizeof(closeCoordinatesArray[0]);
int closeCoordinatesArrayLength = (sizeOfArray / sizeOfFirstObject);
closeCoordinatesArray = realloc(closeCoordinatesArray,sizeof(Coordinate) * (closeCoordinatesArrayLength + 1));
sizeOfArray = sizeof(*closeCoordinatesArray);
sizeOfFirstObject = sizeof(closeCoordinatesArray[0]);
closeCoordinatesArrayLength = (sizeOfArray / sizeOfFirstObject);
After i malloc it in the first row, it shows that its length is 1. I would assume it should be 0 (i want it to be 0).
After a realloc it in case 0 I check the length and it's still 1.
What am i doing wrong?
It's important to remember that sizeof is evaluated at compile time; therefore it could not know about a variable length array. All it gives you is the size of the implicit pointer associated with the array. (Remember that in C pointers and arrays are equivalent).

C Memory Management Issue

I have traced an EXC_BAD_ACCESS to the following allocation and deallocation of memory. It involves the accelerate framework in Xcode. The main issue is that this code is in a loop. If i force the loop to only iterate once then it works fine. But when it loops (7 times) it causes an error on the second iteration. Does any of this look incorrect?
EDIT: *added actual code. This segment runs if I remove certain parts and such but seems to have poor memory management which results in issues
#import <Foundation/Foundation.h>
#include <math.h>
#include <Accelerate/Accelerate.h>
for(int i = 0; i < 8; i++)
{
int XX[M][m]; //M and m are just 2 ints
for(int kk = 0; kk < M; kk++)
{
for (int kk1 = 0; kk1 < m; kk1++)
{
XX[kk][kk1] = [[x objectAtIndex: (kk + kk1 * J)] intValue]; //x is a NSMutableArray of NSNumber objects
}
}
double FreqRes = (double) freqSamp/n;
NSMutableArray *freqs = [[NSMutableArray alloc] initWithCapacity: round((freqSamp/2 - FreqRes) - 1)];
int freqSum = 0;
for(double i = -1 * freqSamp/2; i < (freqSamp/2 - FreqRes); i+= FreqRes)
{
[freqs addObject: [NSNumber numberWithInt: i]];
if(i == 0)
{
freqSum++;
}
}
int num = [x count];
int log2n = (int) log2f(num);
int nOver2 = n / 2;
FFTSetupD fftSetup = vDSP_create_fftsetupD (log2n, kFFTRadix2);
double ffx[num];
DSPDoubleSplitComplex fft_data;
fft_data.realp = malloc(nOver2 * sizeof(double)); //Error usually thrown on this line in the second iteration. Regardless of what I put there. If I add an NSLog here it throws the error on that NSLog
fft_data.imagp = malloc(nOver2 * sizeof(double));
for (int i = 0; i < n; ++i)
{
ffx[i] = [[x objectAtIndex:i] doubleValue];
}
vDSP_ctozD((DSPDoubleComplex *) ffx, 2, &fft_data, 1, nOver2);
vDSP_fft_zripD (fftSetup, &fft_data, 1, log2n, kFFTDirection_Forward);
for (int i = 0; i < nOver2; ++i)
{
fft_data.realp[i] *= 0.5;
fft_data.imagp[i] *= 0.5;
}
int temp = 1;
ffx[0] = abs(fft_data.realp[0]);
for(int i = 1; i < nOver2; i++)
ffx[i] = sqrt((fft_data.realp[i] * fft_data.realp[i]) + (fft_data.imagp[i] * fft_data.imagp[i]));
ffx[nOver2] = abs(fft_data.imagp[0]);
for(int i = nOver2-1; i > 0; i--)
{
ffx[nOver2 + temp] = sqrt((fft_data.realp[i] * fft_data.realp[i]) + (fft_data.imagp[i] * fft_data.imagp[i]));
temp++;
}
//clear Fxx and freqs data
vDSP_destroy_fftsetupD(fftSetup);
free(fft_data.imagp);
free(fft_data.realp);
[freqs release];
}
Your problem could be that you are casting malloc to a value. As you're tagging this c, I'm assuming that you are compiling in c in which case you should see this answer to a previous question as to why casting with malloc is bad:
https://stackoverflow.com/a/1565552/1515720
you can get an unpredictable runtime error when using the cast without including stdlib.h.
So the error on your side is not the cast, but forgetting to include stdlib.h. Compilers may assume that malloc is a function returning int, therefore converting the void* pointer actually returned by malloc to int and then to your your pointer type due to the explicit cast. On some platforms, int and pointers may take up different numbers of bytes, so the type conversions may lead to data corruption.
Regardless though, as the answer says, YOU SHOULD NOT BE CASTING MALLOC RETURNS, because void*'s are safely implicitly converted to whatever you are assigning it to.
As another answerer stated:
vDSP_destroy_fftsetupD(fftSetup);
Could be also free'ing the memory you allocated on accident.
Any chance the destructor of DSPDoubleSplitComplex is freeing up those two allocated blocks?
It could also be that you are only allowed to call vDSP_create_fftsetupD and vDSP_destroy_fftsetupD once during your process's lifetime

Resources