How i delete float 2D array in c++, with QT - c++

Hi I'm using QT to my work and i can't delete a 2D float array from memory.
I'm working with images, so I need delete arrays for not consume much memory.
I tried this way but doesn't work:
int n = test.cols; // number of colums image.
int m = test.rows; // number of lines image
float soma[test.cols][test.rows]; // create a array 2D for operations...
for(int i = 0 ; i < n + 2 ; ++i)
{
for(int j = 0 ; j < m + 2 ; ++j) delete[] soma[i][j] ;
delete[] soma[i];
}
delete[] soma;

In this particular case the array is either on the STACK or in the DATA section of memory, not the HEAP. Only memory in the HEAP that is allocated with new[] can be deleted by the delete[] operator.
Not this example creates a series of discontinuous rows all over memory.
If you allocated the memory like this.
float ** soma = new float* [test.rows];
// WARNING UNITIALIZED CONTENT
for(int i = 0 ; i < test.rows; ++i) soma[i] = new float[test.cols];
You could then delete the memory like this
for(int i = 0 ; i < test.rows; ++i) delete [] soma[i];
delete [] soma;
However it is often better to allocate a single continuous image (if the dimensions are not too big). You then use a second array to record row offsets as pointers.
// WARNING UNITIALIZED CONTENT
float * buffer = new float [ test.rows * test.cols ]
float ** soma = new float* [ test.rows ];
for(int i = 0 ; i < m; ++i) soma[i] = soma + i * test.cols;
Then delete it like this
delete [] soma;
delete [] buffer;
Or just use std::vector.

Thx, i use std::vector, i'm working with images, static allocation is not a good way, so i use std::vector, for this work, Thank you for your attention, , follow my code now:
vector <float> lines(test.rows);
vector<vector<float> > colums(test.cols,lines);
for(int i=0;i<colums.size(); i++) {
for (int j=0;j<colums[i].size(); j++){
colums[i][j] = ((float)imagem.at<Vec3b>(j,i)[0]/(float)(imagem.at<Vec3b>(j,i)[0] + (float)imagem.at<Vec3b>(j,i) [1] + (float)imagem.at<Vec3b>(j,i) [2]))*255;
aux = (int) floor(colums[i][j] + 0.5);
colums[i][j] = aux;
test.at<Vec3b>(j, i)[0] = aux;
aux = 0;
colums[i][j] = ((float)imagem.at<Vec3b>(j,i)[1]/
(float)(imagem.at<Vec3b>(j,i)[0] +
(float)imagem.at<Vec3b>(j,i) [1] +
(float)imagem.at<Vec3b>(j,i) [2]))*255;
aux = (int) floor(colums[i][j] + 0.5);
colums[i][j] = aux;
test.at<Vec3b>(j, i)[1] = aux;
aux = 0;
colums[i][j] = ((float)imagem.at<Vec3b>(j,i)[2]/
(float)(imagem.at<Vec3b>(j,i)[0] +
(float)imagem.at<Vec3b>(j,i) [1] +
(float)imagem.at<Vec3b>(j,i) [2]))*255;
aux = (int) floor(colums[i][j] + 0.5);
colums[i][j] = aux;
test.at<Vec3b>(j, i)[2] = aux;
aux = 0;
}
}

Related

Receive values from dynamic array

I recently asked question about how to work with element Edit1 dynamically, now I want to ask something about values, which I received from dynamical arrays. First I try to divide image into sectors:
const n=20;
unsigned short i, j, line_length, w = Image1->Width, h = Image1->Height, l = Left + Image1->Left, t = Top + Image1->Top;
unsigned short border = (Width-ClientWidth)/2, topborder = Height-ClientHeight-border;
Image1->Canvas->Pen->Color = clRed;
for (i = 0; i <= n; i++)
{
Image1->Canvas->MoveTo(0, 0);
line_length = w * tan(M_PI/2*i/n);
if (line_length <= h)
Image1->Canvas->LineTo(w, line_length);
else
{
line_length = h * tan(M_PI/2*(1-1.*i/n));
Image1->Canvas->LineTo(line_length, h);
}
}
Then I use regions to count black dots in each sector and I want to add values to element Memo:
HRGN region[n];
TPoint points[3];
points[0] = Point(l + border, t + topborder);
for (i = 0; i < n; i++)
{
for (j = 0; j <= 1; j++)
{
line_length = w * tan(M_PI/2*(i+j)/n);
if (line_length <= h)
points[j+1] = Point(l + border + w, t + topborder + line_length);
else
{
line_length = h * tan(M_PI/2*(1-1.*(i+j)/n));
points[j+1] = Point(l + border + line_length, t + topborder + h);
}
}
region[i] = CreatePolygonRgn(points, 3, ALTERNATE); // or WINDING ?? as u want
}
Byte k;
unsigned __int64 point_count[n] = {0}, points_count = 0;
for(j = 0; j < h; j++)
for (i = 0; i < w; i++)
if (Image1->Canvas->Pixels[i][j] == clBlack)
{
points_count++;
for (k = 0; k < n; k++)
if (PtInRegion(region[k], l + border + i, t + topborder + j))
point_count[k]++;
}
unsigned __int64 sum = 0;
for (i = 0; i < n; i++)
{
sum += point_count[i];
Memo1->Lines->Add(point_count[i]);
}
As i received an advice from one man, in order to allocate an array using a TEdit to specify the array's count I should use, for example DynamicArray:
#include <sysdyn.h>
DynamicArray<HRGN> region;
...
int n = Edit1-> Text.ToInt();
region.Length = n;
I have made the same changes to point_count array:
Byte k;
DynamicArray<unsigned __int64> point_count;
point_count.Length = n;
unsigned __int64 /*point_count[n] = {0},*/ points_count = 0;
...
The problem is that I received different values if I do it dynamically or statically(n=20).
Statically:
Dynamically:
The problem is that I received different values if I do it dynamically or statically(n=20)
There is no difference whatsoever in accessing elements of a static array vs a dynamic array. Your problem has to be elsewhere.
For instance, your static code is initializing all of the array elements to 0, but your dynamic code is not doing that, so they will have random values before your loop then increments them.
Try this:
DynamicArray<unsigned __int64> point_count;
point_count.Length = n;
for(int i = 0; i < n; ++i) {
point_count[i] = 0;
}
...
Alternatively:
DynamicArray<unsigned __int64> point_count;
point_count.Length = n;
ZeroMemory(&point_count[0], sizeof(unsigned __int64) * n);
...
Also, using the Image1->Canvas->Pixels[][] property is very slow. Consider using the Image1->Picture->Bitmap->ScanLine[] property instead for faster access to the raw pixels.

Error "subscript of pointer to function type 'int *(int)'"

I am writing a code to find a cluster, I am using "cern root" to plot graphs,
the data is saved in ".root" file, but the code is written in c++. The data is saved as a 2D histogram. The logic of the code is once I find a bin with some signal in it, I find the neighbours around it (8 bins), then I tag the bin and increase the cluster size, and then do the same for the neighbour. I started by making a fiction to find the neighbour (the function returns an array with the x coordinate and another finds the y coordinate)
int* neighbour_function_i(int i){
int* neighbour_i = new int[8]; // Pointer to int, initialize to nothing.
neighbour_i[0] = {i-1}, neighbour_i[1] = {i}, neighbour_i[2] = {i+1}, neighbour_i[3] = {i-1}, neighbour_i[4] = {i+1}, neighbour_i[5] = {i-1}, neighbour_i[6] = {i}, neighbour_i[7] = {i+1};
return neighbour_i; //check if this works
}
the code that finds the cluster is as below
int* temp_neighbour_i = NULL;
int* temp_neightbour_j = NULL;
int uncheckedneighbours, total_neighbours;
int clsize = 0;
int temp_i,temp_j;
for(int i = 0; i < NPIXAX; i++){
for(int j = 0; j < NPIXAY; j++){
clsize = 0;
if(h->GetBinContent(i + 1, j + 1) - ped[i][j] > 0 && pedbf[i][j] == 0){//condition to find a cluster
pedbf[i][j] = 1; //Tag arry
clsize = 1;
uncheckedneighbours = 8;
total_neighbours = uncheckedneighbours;
int* neighbour_i = neighbour_function_i[i];//the error is here
int* neighbour_j = neighbour_function_j[j];//the error is here
while(uncheckedneighbours != 0){
for(int n = 0; n < total_neighbours; n++){
temp_i = neighbour_i[n];//Temp int for coordienate
temp_j = neighbour_j[n];//Temp int for coordinate
if(h->GetBinContent(temp_i, temp_j) - ped[temp_i][temp_j] > 0 && pedbf[temp_i][temp_j] == 0){//condition to find a cluster
pedbf[temp_i][temp_j] = 1;
int* new_neighbour_i = neighbour_function_i[temp_i];//the error is here
int* new_neighbour_j = neighbour_function_j[temp_j];//the error is here
uncheckedneighbours += 8;
total_neighbours += 8;
int* temp_neighbour_i = new int[clsize * 8];
int* temp_neighbour_j = new int[clsize * 8];
clsize++;
temp_neighbour_i[n] = neighbour_i[n];//moving data to chnage the size of neighbour/i array
temp_neighbour_j[n] = neighbour_j[n];//moving data to change the size of neighbour_j array
delete[] neighbour_i;//deallocate neighbour
delete[] neighbour_j;//deallocate neighbour
int *neighbour_i = new int[clsize * 8]; //re-allocate the size of neighbour with size = size(clsize *8)
int *neighbour_j = new int[clsize * 8]; //re-allocate the size of neighbour with size = size(clsize *8)
for(int x = 0; x < (clsize - 1) * 8; x++){ //neighbour = temp_neighbour + new_neighbour
neighbour_i[x] = temp_neighbour_i[x];
neighbour_j[x] = temp_neighbour_j[x];
}
for(int x = (clsize - 1)*8; x < clsize * 8; x++){
neighbour_i[x] = new_neighbour_i[x];
neighbour_j[x] = new_neighbour_j[x];
}
delete[]temp_neighbour_i; //dealocate temp and new
delete[]temp_neighbour_j; //dealocate temp and new
delete[]new_neighbour_i; //dealocate temp and new
delete[]new_neighbour_j; //dealocate temp and new
}
uncheckedneighbours--;
}
}
//if(clsize != 0){;//output to file cluseter size, i, j
//}
}
}
}
I am not sure why I am getting this error "subscript of pointer to function type 'int *(int)'"?
Maybe question should be closed as typo, but a function gets called like this:
int* neighbour_i = neighbour_function_i(i);
Not like this:
int* neighbour_i = neighbour_function_i[i];

FFTW Complex to Real Segmentation Fault

I am attempting to write a naive implementation of the Short-Time Fourier Transform using consecutive FFT frames in time, calculated using the FFTW library, but I am getting a Segmentation fault and cannot work out why.
My code is as below:
// load in audio
AudioFile<double> audioFile;
audioFile.load ("assets/example-audio/file_example_WAV_1MG.wav");
int N = audioFile.getNumSamplesPerChannel();
// make stereo audio mono
double fileDataMono[N];
if (audioFile.isStereo())
for (int i = 0; i < N; i++)
fileDataMono[i] = ( audioFile.samples[0][i] + audioFile.samples[1][i] ) / 2;
// setup stft
// (test transform, presently unoptimized)
int stepSize = 512;
int M = 2048; // fft size
int noOfFrames = (N-(M-stepSize))/stepSize;
// create Hamming window vector
double w[M];
for (int m = 0; m < M; m++) {
w[m] = 0.53836 - 0.46164 * cos( 2*M_PI*m / M );
}
double* input;
// (pads input array if necessary)
if ( (N-(M-stepSize))%stepSize != 0) {
noOfFrames += 1;
int amountOfZeroPadding = stepSize - (N-(M-stepSize))%stepSize;
double ipt[N + amountOfZeroPadding];
for (int i = 0; i < N; i++) // copy values from fileDataMono into input
ipt[i] = fileDataMono[i];
for (int i = 0; i < amountOfZeroPadding; i++)
ipt[N + i] = 0;
input = ipt;
} else {
input = fileDataMono;
}
// compute stft
fftw_complex* stft[noOfFrames];
double frames[noOfFrames][M];
fftw_plan fftPlan;
for (int i = 0; i < noOfFrames; i++) {
stft[i] = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * M);
for (int m = 0; m < M; m++)
frames[i][m] = input[i*stepSize + m] * w[m];
fftPlan = fftw_plan_dft_r2c_1d(M, frames[i], stft[i], FFTW_ESTIMATE);
fftw_execute(fftPlan);
}
// compute istft
double* outputFrames[noOfFrames];
double output[N];
for (int i = 0; i < noOfFrames; i++) {
outputFrames[i] = (double*)fftw_malloc(sizeof(double) * M);
fftPlan = fftw_plan_dft_c2r_1d(M, stft[i], outputFrames[i], FFTW_ESTIMATE);
fftw_execute(fftPlan);
for (int m = 0; i < M; m++) {
output[i*stepSize + m] += outputFrames[i][m];
}
}
fftw_destroy_plan(fftPlan);
for (int i = 0; i < noOfFrames; i++) {
fftw_free(stft[i]);
fftw_free(outputFrames[i]);
}
// output audio
AudioFile<double>::AudioBuffer outputBuffer;
outputBuffer.resize (1);
outputBuffer[0].resize(N);
outputBuffer[0].assign(output, output+N);
bool ok = audioFile.setAudioBuffer(outputBuffer);
audioFile.setAudioBufferSize (1, N);
audioFile.setBitDepth (16);
audioFile.setSampleRate (8000);
audioFile.save ("out/audioOutput.wav");
The segfault seems to be being raised by the first fftw_malloc when computing the forward STFT.
Thanks in advance!
The relevant bit of code is:
double* input;
if ( (N-(M-stepSize))%stepSize != 0) {
double ipt[N + amountOfZeroPadding];
//...
input = ipt;
}
//...
input[i*stepSize + m];
Your input pointer points at memory that exists only inside the if statement. The closing brace denotes the end of the lifetime of the ipt array. When dereferencing the pointer later, you are addressing memory that no longer exists.

I need to specify the size of an array dynamically

I have a Nx3 array which I need to fill as a function (so vector isn't an option). I already know how big N as as I feed it into the function as a parameter. I still get this stupid error of "must have a constant value", my code is:
double bspline_plot(double CP[], double Knot[], const int N, int d, int ncontrol, double *A){
// CP are the control points
//Knot is the knot vector
//N is the number of internal point you want in each segment
//d is the degree of the polynomials
double min_x, max_x, dx;
double *x_1;
x_1 = new double[N];
double A[N][2];
int i, j, M, L;
min_x = min(Knot);
max_x = max(Knot);
dx = (max_x - min_x) / N;
for (i = 0; i <= N; i = i + 1)
{
x_1[i] = min_x + dx*i;
}
M = ncontrol;
L = (sizeof(Knot) / sizeof(*Knot));
if (L < d + M + 1) // This checks if the number of control points are positive
{
printf("Incorrectly defined knot vector\n");
return;
}
else //This is the Cox - deBoor algorithm
{
for (i = 0; i <= N; i = i + 1)
{
for (j = 0; j <= L - 1; j = j + 1)
{
A[i][1] = A[i][1] + CP[j, 1] * CdB(j, d, x_1[i], Knot);
A[i][2] = A[i][2] + CP[j, 2] * CdB(j, d, x_1[i], Knot);
A[i][3] = A[i][3] + CP[j, 3] * CdB(j, d, x_1[i], Knot);
}
A[N][1] = CP[L, 2];
A[N][2] = CP[L, 2];
A[N][3] = CP[L, 1];
}
}
return A;
}
My other option is to feed in an array and then find it's values in the function but that seems a bit silly.
try to use std::vector in following way:
std::vector<std::vector<double>> A( N );
for( auto& row : A )
row.resize( M );
or
std::vector<std::vector<double>> A( N, std::vector<double>( M ));
From a quick inspection, the problem in your C++ code appears to be the following array declaration:
double A[N][2];
You need to dynamically allocate this 2d array as follows:
double** A = new double*[N];
for (int i=0; i<N; ++i)
A[i] = new double[2];
Have a look at this SO article for more information.
In the end I had to split A up into three vectors and change the output of the function from double to void and read in the (now) three vectors as double*. I can then just change the contents of the vectors and it now is showing no errors.

Access three dimensional array via pointer

How do I access a three-dimensional array via pointers? At the moment I have this code, trying to get the same results. I need the access via pointers to use the values in the array in OpenCL.
for (l = 0; l < NumberOfLayers - 1; l++) {
for (i = 0; i < NeuronsPerLayer[l]; i++) {
for (j = 0; j < NeuronsPerLayer[l + 1] - bias[l + 1]; j++) {
cout<<Synweights[l][i][j]<<endl;
cout<<*(*Synweights[0]+l*NumberOfLayers + i * NeuronsPerLayer[l] + j)<<endl;
}
}
}
Synweights is declared as:
double ***Synweights
Synweights = (double ** *)malloc((NumberOfLayers - 1) * sizeof(double **));
for (l = 0; l < NumberOfLayers - 1; l++) {
Synweights[l] = (double **)malloc(NeuronsPerLayer[l] * sizeof(double *));
for (i = 0; i < NeuronsPerLayer[l]; i++) {
Synweights[l][i] = (double *)malloc((NeuronsPerLayer[l + 1] - bias[l + 1]) * sizeof(double));
}
}
It depends on the structure of your arrays.
Synweights is an array of arrays of arrays which means there are many memory blocks at different locations. If you have a pointer to such a structure you can do the very same with a pointer:
float p*** = new float**[sizeL];
for(int l=0; l<sizeL; ++l)
{
p[l] = new float*[sizeI];
for(int i=0; i<sizeI; ++i)
p[l][i] = new float[sizeJ];
}
...
p[l][i][j] = 0; // Access
In case you have just on block of memory which is interpreted as 3D array you need to do some arithmetic. This should be the case you need for CpenCL anyway.
float* p = new float[sizeL*sizeI*sizeJ];
...
p[(l*sizeI+i)*sizeJ+j] = 0; // Access
p + ((l*sizeI+i)*sizeJ+j); // Direct address/pointer calculation
This variant is faster due to cache performance and less address computations. You can store the computed index if you intend to access more than once.
A three dimensional array may be accessed in the following way;
T* myArray = new T[3][4][5];
T* aParticularT = myArray[1][2][2];
T* anArrayOfTs = myArray[1][2];
T* aTwoDimensionalArrayOfTs = myArray[1];
T* aThreeDimensionalArrayOfTs = myArray;
aTypeName aMemberOfT = aParticularT->memberName;