How to Access Array three-dimensional in position 2 c++ - c++

I have a problem to get access to the second position of a three-dimensional array.
See code:
int qtdMosquitos = 2500000;
int altura = 500, largura = 500, i, j, k, qtdMosquitoPorCelula = qtdMosquitos /(altura*largura);
long id = 1;
Mosquito* mosquitos[qtdMosquitos][qtdMosquitos][qtdMosquitoPorCelula];
Mosquito* listaMosquitos[qtdMosquitoPorCelula];
for (i = 0; i < altura; i++) {
for (j = 0; j < largura; j++) {
for (k = 0; k < qtdMosquitoPorCelula; k++) {
Mosquito* mosquito = new Mosquito();
mosquito->setId(id);
mosquito->setState("S");
listaMosquitos[k] = mosquito;
}
mosquitos[i][j] = listaMosquitos;
}
}
Line mosquitos[i][j] = listaMosquitos; displays the following error:
main.cpp|24|error: invalid array assignment|
I understand what error says, but I can not find the cause, we already created the instance of the 3D matrix with the same variable that is created the simple array, variable qtdMosquitoPorCelula.
Could you help me set a value for the 3D array?
As follows: matrix[0][1] = arraySimples;

Since the array in C is the pointer of the first element of the array. Therefore, the code
mosquitos[i][j] = listaMosquitos;
means assigning the pointer of listaMosquitos[0] to mosquitos[i][j][0] which will cause memory issue and the compile will prohibit it.
In the code sample, we can do the same thing with the following code sample:
.....
for (i = 0; i < altura; i++) {
for (j = 0; j < largura; j++) {
for (k = 0; k < qtdMosquitoPorCelula; k++) {
Mosquito* mosquito = new Mosquito();
mosquito->setId(id);
mosquito->setState("S");
listaMosquitos[k] = mosquito;
mosquitos[i][j][k] = mosquito;
}
}
}

Related

How to return a 2D array in C++ using pointers, the error I get is "Cannot convert 'int (*)[size]' to 'int**'

I am currently building a median filter in C++. I have a decent amount of experience with other languages but C++ and its pointers confuse me. I am building a function which takes in a 2D array of RGB values of an image. The function may not be 100% yet but I just cannot get past returning the 2d array. My input parameters is the row major version of the image array and the filter size and the output is the pointer to the filtered 2D array. It has the following error when debugging >"Cannot convert 'int (*)[size]' to 'int"
Can you possibly walk me through this error and how to deal with it?
Also if you spot any other peculiarities please mention it, it would be greatly appreciated!
int** seq_medFilter(int image[][3], int filter)
{
int output[640 * 480][3];
int rows = 640;
int cols = 480;
int fil_arr_size = pow((2 * filter + 1), 2);
for (int i = 0; i<rows*cols; ++i)
{
int temp[fil_arr_size][3];
//edge cases excluded
int current_col = i / cols;
int current_row = i%cols;
if (current_col < filter || current_col > cols - filter - 1 || current_row < filter || current_row > rows - filter - 1)
{
for (int j = 0; j<3; j++) {
output[i][j] = image[i][j];
}
}
else
{
// just for a filter size of one now
int pos_x = i / cols - filter;
int pos_y = i%cols - filter;
for (int x = 0; x< fil_arr_size - 1; ++x)
{
for (int j = 0; j<3; j++) {
temp[x][j] = image[pos_x*cols + pos_y][j];
}
pos_x += 1;
if (pos_x == (2 * filter + 1))
{
pos_x = pos_x - (2 * filter + 1);
pos_y += 1;
}
}
int N = sizeof(temp) / sizeof(temp[0]);
sort(temp, temp + N);
for (int j = 0; j<3; j++) {
output[i][j] = temp[N / 2][j];
}
}
}
return output;
}
int main()
{
return 0;
}
The issue is that you cannot return a int output[][] as an int **. They are considered different types, but also, output is a local variable, and thus cannot be returned as a pointer without causing UB.
You could use a vector instead, like so:
std::vector<std::vector<int>> seq_medFilter(int image[][3], int filter)
{
std::vector<std::vector<int>> output( 640 * 480, std::vector<int>( 3 ) );
//...
If you insist on using pointers, then you can used unique_ptr/shared_ptr, or use new, though I would say that all three of these options are worse than just using a vector here.
You could also use an std::array
Example:
std::array<std::array<int, 3>, 640*480> seq_medFilter(int image[][3], int filter)
Then, where you declare output, you would change its type to
std::array<std::array<int, 3>, 640*480> output;
Note that the line:
int temp[fil_arr_size][3];
Is not valid in standard C++ (see here).
For completeness, using the pointer method, you would keep your function head the same, but then use:
int **output = new int*[640*480];
for ( size_t idx = 0; idx < 640*480; ++idx ) {
output[idx] = new int[3];
}
Again, I don't recommend this method.

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];

Access violation when reading 2d array C++

My code seems to have a bug somewhere but I just can't catch it. I'm passing a 2d array to three sequential functions. First function populates it, second function modifies the values to 1's and 0's, the third function counts the 1's and 0's. I can access the array easily inside the first two functions, but I get an access violation at the first iteration of the third one.
Main
text_image_data = new int*[img_height];
for (i = 0; i < img_height; i++) {
text_image_data[i] = new int[img_width];
}
cav_length = new int[numb_of_files];
// Start processing - load each image and find max cavity length
for (proc = 0; proc < numb_of_files; proc++)
{
readImage(filles[proc], text_image_data, img_height, img_width);
threshold = makeBinary(text_image_data, img_height, img_width);
cav_length[proc] = measureCavity(bullet[0], img_width, bullet[1], img_height, text_image_data);
}
Functions
int makeBinary(int** img, int height, int width)
{
int threshold = 0;
unsigned long int sum = 0;
for (int k = 0; k < width; k++)
{
sum = sum + img[1][k] + img[2][k] + img[3][k] + img[4][k] + img[5][k];
}
threshold = sum / (width * 5);
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
img[i][j] = img[i][j] > threshold ? 1 : 0;
}
}
return threshold;
}
// Count pixels - find length of cavity here
int measureCavity(int &x, int& width, int &y, int &height, int **img)
{
double mean = 1.;
int maxcount = 0;
int pxcount = 0;
int i = x - 1;
int j;
int pxsum = 0;
for (j = 0; j < height - 2; j++)
{
while (mean > 0.0)
{
for (int ii = i; ii > i - 4; ii--)
{
pxsum = pxsum + img[ii][j] + img[ii][j + 1];
}
mean = pxsum / 4.;
pxcount += 2;
i += 2;
pxsum = 0;
}
maxcount = std::max(maxcount, pxcount);
pxcount = 0;
j++;
}
return maxcount;
}
I keep getting an access violation in the measureCavity() function. I'm passing and accessing the array text_image_data the same way as in makeBinary() and readImage(), and it works just fine for those functions. The size is [550][70], I'm getting the error when trying to access [327][0].
Is there a better, more reliable way to pass this array between the functions?

Convert RGB image in Mat to BYTE * in MFC

Sorry for putting it out here but opencv site is down or something i cannot access the topic there. I am reading a RGB image in Mat and than trying to convert in into BYTE* using the following function but it is not giving me the exact image but distorted part of some of the image. Please can anyone help me out here where i am mistaking it. Thank you.
BYTE *change_to_BYTE(Mat matrix_value)
{
BYTE* v_char_new = new BYTE[matrix_value.rows * matrix_value.cols * 3]();
vector<byte> v_char;
for(int i = 0; i < matrix_value.rows; i++)
{
for(int j = 0; j < matrix_value.cols; j++)
{
v_char_new[((i*matrix_value.cols+j) * 3)+0] = (*(uchar*)((matrix_value.data+ i*matrix_value.step + j + 0)));
v_char_new[((i*matrix_value.cols+j) * 3)+1] = (*(uchar*)((matrix_value.data+ i*matrix_value.step + j +1)));
v_char_new[((i*matrix_value.cols+j) * 3)+2] = (*(uchar*)((matrix_value.data+ i*matrix_value.step + j +2)));
}
}
return v_char_new;
}
After checking it out in different ways this was the one that worked for me.
BYTE *Ctest_face_projectDlg::change_to_BYTE(Mat matrix_value)
{
BYTE* v_char_new = new BYTE[matrix_value.rows * matrix_value.cols * 3]();
for(int i = 0; i < matrix_value.rows; i++)
{
for(int j = 0; j < matrix_value.cols; j++)
{
Vec3b bgrPixel = matrix_value.at<Vec3b>(i, j);
v_char_new[((i*matrix_value.cols+j)*3)+0] = bgrPixel.val[0];
v_char_new[((i*matrix_value.cols+j)*3)+1] = bgrPixel.val[1];
v_char_new[((i*matrix_value.cols+j)*3)+2] = bgrPixel.val[2];
// do something with BGR values...
}
}
}