Access violation writing location 0x00000000 in middle of a for loop - visual-studio

I'm trying to use mnist dataset for neural networks but im getting a Access violation writing location 0x00000000
the code is
for (int i = 0; i < length; i++) {
innerarray = (int8_t*)malloc(width * height);
for (int j = 0; j < width * height; j++) {
int8_t value = 0;
innerarray[j] = value;
}
temparray[i] = innerarray;
}
for (int i = 0; i < length; i++) {
for (int j = 0; j < width * height; j++) {
int8_t grayscale;
rf.read((char*)&grayscale, 1);
temparray[i][j] = grayscale; //error happens here
}
}
variable values:
int length = 10000;
int width = 28;
int height = 28;
The weird thing is it only happen when i >= 2512. Also replacing grayscale with 0 doesn't work. I can hower set temparray[2512][0] to 0 before the last nested for loop.
Like this:
for (int i = 0; i < length; i++) {
innerarray = (int8_t*)malloc(width * height);
for (int j = 0; j < width * height; j++) {
int8_t value = 0;
innerarray[j] = value;
}
temparray[i] = innerarray;
}
temparray[2512][0] = 0; //works
for (int i = 0; i < length; i++) {
for (int j = 0; j < width * height; j++) {
int8_t grayscale;
rf.read((char*)&grayscale, 1);
temparray[i][j] = 0; //error still happens here
}
}
The full code is:
#include<iostream>
#include<fstream>
#include<cstdint>
#include<cstdlib>
#include<array>
using namespace std;
struct images {
int32_t height = 0;
int32_t width = 0;
int32_t magicnumber = 0;
int32_t numberofimages = 0;
int8_t** images[];
void setimages(int8_t** newimages) {
delete[] this->images;
int8_t** images = (int8_t**)malloc(numberofimages);
int8_t* innerarray;
for (int i = 0; i < numberofimages; i++) {
innerarray = (int8_t*)malloc(width * height);
images[i] = innerarray;
}
for (int i = 0; i < numberofimages; i++) {
for (int j = 0; j < width * height; j++) {
images[i][j] = newimages[i][j];
}
}
};
};
struct labels {
int32_t magicnumber = 0;
int32_t numberoflabels = 0;
int8_t labels[];
};
int32_t litleendiantobig(int32_t litle) {//reverse works as well
int32_t big = ((4278190080 & litle) >> 24) + ((255 & litle) << 24) + ((16711680 & litle) >> 8) + ((65280 & litle) << 8);
return big;
}
images loadimages(string filename, int32_t magicalnumber) {
ifstream rf(filename, ios::out | ios::binary);
if (!rf) {
cout << "Cannot open file! " << filename << endl;
exit(1);
}
int32_t magicnumberoffile;
rf.read((char*)&magicnumberoffile, 4);
magicnumberoffile = litleendiantobig(magicnumberoffile);
if (magicalnumber != magicnumberoffile) {
cout << "Wrong magic number!" << endl;
cout << "expected:" << magicalnumber << endl;
cout << "got:" << magicnumberoffile << endl;
exit(1);
}
images img;
int32_t length;
rf.read((char*)&length, 4);
length = litleendiantobig(length);
img.numberofimages = length;
int32_t width;
rf.read((char*)&width, 4);
width = litleendiantobig(width);
img.width = width;
int32_t height;
rf.read((char*)&height, 4);
height = litleendiantobig(height);
img.height = height;
int8_t** temparray = (int8_t**)malloc(length);
int8_t* innerarray;
for (int i = 0; i < length; i++) {
innerarray = (int8_t*)malloc(width * height);
for (int j = 0; j < width * height; j++) {
int8_t value = 0;
innerarray[j] = value;
}
temparray[i] = innerarray;
}
for (int i = 0; i < length; i++) {
for (int j = 0; j < width * height; j++) {
int8_t grayscale;
rf.read((char*)&grayscale, 1);
temparray[i][j] = grayscale; //error happens here
}
}
img.setimages(temparray);
rf.close();
return img;
}
int main() {
images testimages;
loadimages("t10k-images.bin", 2051);
cout << testimages.images;
return 0;
}
I don't now how to solve the problem and can't find it anywhere else. Thanks for helping me out.

Your using malloc has done you in.
int* array = (int*)malloc(width* height); // allocate width * height bytes.
array[i] = x; // Sets the [i] _integer_ of array to x.
// but you allocated space for BYTE size elemennts.
The correct way to allocate integers using malloc:
int* array = (int*)malloc(width* height * sizeof(int)); // allocate width * height ints
Either that or your original intent was to allocate 8 bit pixels. In that case, your pointers should be declared as unsigned char*.
In either case, when coding in C++, types are important, and using operator new to allocate your arrays would have saved you from these troubles.

Related

Why does my won't my code populate the matrix?

My code is trying to find the beginning and ending indices of a section of a matrix that when added, together would equal 20. For each instance this occurs, it would then populate a matrix with said beginning and end indices in the format {beginning row index, beginning column index, ending row index, ending column index} for each row. Each row would represent separate instances. It works fine for one instance but when introduced to other instances it wouldn't populate the matrix. Please help.
#include <cstddef> // size_t
#include <iostream>
using namespace std;
// Populates matrix
void filler(int bIndr, int bIndc, int eIndr, int eIndc, size_t**matrix, const size_t kIndices_size2, const size_t kIndices_size) {
int t = 0;
int matrix2[4] = {0,0,0,0};
for(int i = 0 ; i < kIndices_size2; i++) {
for (int j = 0; j < 2; j++) {
for (int ii = t; ii < kIndices_size; ii++) {
if(j == 0) {
matrix2[ii] = bIndr;
matrix2[ii+1] = bIndc;
cout << matrix2[ii+1] << endl;
break;
}
if(j == 1) {
matrix2[ii] = eIndr;
matrix2[ii+1] = eIndc;
cout << matrix2[ii+1] << endl;
break;
}
}
t = 2;
}
}
for(int i = 0 ; i < kIndices_size; i++) {
matrix[kIndices_size2-1][i] = matrix2[i];
}
}
int main()
{
int goal = 20;
int array[2][8] = {{10,0,0,10,0,0,1,0},{0,0,10,0,0,0,10,0}};
int inst = 0;
int t=0;
int bIndr = 0;
int bIndc = 0;
int eIndr = 0;
int eIndc = 0;
const size_t kIndices_size = 4;
size_t**matrix;
for(int ii = 0; ii < 2; ii++) {
bIndc =0;
for(int j = bIndc; j < 8; j++) {
t = 0;
bIndr = ii;
bIndc = j;
for(int i = j; i < 8; i++) {
t += array[ii][i];
if((goal-t) == 0) {
inst++;
eIndc = i;
eIndr = ii;
matrix=new size_t*[inst];
matrix[inst-1]=new size_t [kIndices_size];
cout << bIndr << bIndc << eIndr << eIndc << endl;
filler(bIndr, bIndc, eIndr, eIndc, matrix, inst, kIndices_size);
break;
}
}
}
}
size_t actual_size = static_cast<size_t>(-1);
cout << actual_size << endl;
size_t* sums_found = &actual_size;
*sums_found = inst;
cout << actual_size << endl;
cout << matrix[0][0] << endl;
for(int i = 0; i < inst; i++) {
for(int ii = 0; ii < kIndices_size; ii++) {
cout << matrix[i][ii] << " ";
}
cout << endl;
}
return 0;
}

Digital Image Processing Contrast Stretching Histogram

Here I attach my code that I use to Draw the Histogram of the Contrasted image and also to convert a gray image into Contrast Image. Here I used low pint as 122 and highest point as 244. In the output histogram it reduce the height of the histogram.
I cannot find the error in my code
#include "opencv2/opencv.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/core.hpp"
using namespace cv;
using namespace std;
int main(int argc, char* argv[]) {
Mat img = imread(argv[1], 1);
if (!img.data) {
cout << "Could not find the image!" << endl;
return -1;
}
int height = img.rows;
int width = img.cols;
int widthstep = img.step;
int ch = img.channels();
printf("Height : %d\n", height);
printf("Width : %d\n", width);
printf("Widthstep : %d\n", widthstep);
printf("No of channels : %d\n", ch);
Mat gray_image(height, width, CV_8UC1, Scalar(0));
cvtColor(img, gray_image, COLOR_BGR2GRAY);
Mat new_image = gray_image.clone();
int v;
int output{};
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int v = (int)gray_image.at<uchar>(y, x);
if (v >= 0 && v <= 122) {
output = int((6 / 122) * v);
}
else if (v > 100 && v <= 244) {
output = int(((244) / (122)) * (v - 122) + 6);
}
else if (v > 244 && v <= 255) {
output = int(((5) / (11)) * (v - 244) + 250);
}
new_image.at<uchar>(y, x) = (uchar)output;
}
}
int histn[256];
for (int i = 0; i < 256; i++) {
histn[i] = 0;
}
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
histn[(int)new_image.at<uchar>(y, x)] = histn[(int)new_image.at<uchar>(y, x)] + 1;
}
}
for (int i = 0; i < 256; i++) {
cout << i << ":" << histn[i] << endl;
}
int hist_wn = 512;
int hist_hn = 400;
int bin_wn = cvRound((double)hist_wn / 256);
Mat new_histogramImage(hist_hn, hist_wn, CV_8UC1, Scalar(255));
int maxn = histn[0];
for (int i = 0; i < 256; i++) {
if (maxn < histn[i]) {
maxn = histn[i];
}
}
for (int i = 0; i < 256; i++) {
histn[i] = ((double)histn[i] / maxn) * new_histogramImage.rows;
}
for (int i = 0; i < 256; i++) {
line(new_histogramImage, Point(bin_wn * (i), hist_hn), Point(bin_wn * (i), hist_hn - histn[i]), Scalar(0), 1, 8, 0);
}
imwrite("Gray_Image.png", gray_image);
imwrite("newcontrast_Image.png", new_image);
imwrite("Histogram.png", new_histogramImage);
namedWindow("Image");
imshow("Image", img);
namedWindow("Gray_Image");
imshow("Gray_Image", gray_image);
namedWindow("newcontrast_Image");
imshow("newcontrast_Image", new_image);
namedWindow("New_Histogram");
imshow("New_Histogram", new_histogramImage);
namedWindow("Old_Histogram");
imshow("Old_Histogram", histImage);
waitKey(0);
return 0;
}
Here are the new and old histograms that I got as outputs
I found the solution for the question. Here I changed the lowest and highest point values as 100 and 240 and when using the values set those as decimals values.
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int v = (int)gray_image.at<uchar>(y, x);
if (v >= 0 && v <= 100) {
output = int((5.0/ 100.0) * v);
}
else if (v > 100 && v <= 240) {
output = int(((245.0) / (140.0)) * (v - 100.0) + 5.0);
}
else if (v > 240 && v <= 255) {
output = int(((5.0) / (15.0)) * (v - 240.0) + 250.0);
}
new_image.at<uchar>(y, x) = (uchar)output;
}
}

Thrust's exclusive_scan_by_key function takes the same amount of time as a sequential implementation?

I'm relatively new to Thrust and I'm trying to perform a segmented scan. Here is my code, which you should be able to run as-is:
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/execution_policy.h>
#include <chrono>
// Sequential scan for CPU
float* test_seqScan(float* in, int s, int m) {
float* out = new float[s * m];
for (unsigned int i = 0; i < s; i++) {
out[i * m] = 0;
}
for (unsigned int i = 0; i < s; i++) {
for (unsigned int j = 1; j < m; j++) {
out[i * m + j] = out[i * m + j - 1] + in[i * m + j - 1];
}
}
return out;
}
void test_sumScan(thrust::device_vector<float> dev_in, thrust::device_vector<int> dev_keys, int s, int m) {
// Allocate device memory for output
thrust::device_vector<float> dev_out(s * m);
thrust::exclusive_scan_by_key(thrust::device, dev_keys.begin(), dev_keys.end(), dev_in.begin(), dev_out.begin());
}
int main(){
int s = 100;
int m = 100000;
float* seq_in = new float[s * m];
for (int i = 0; i < s; i++) {
for (int j = 0; j < m; j++) {
seq_in[i * m + j] = j + 1;
}
}
thrust::host_vector<float> par_in(s * m);
for (int i = 0; i < s; i++) {
for (int j = 0; j < m; j++) {
par_in[i * m + j] = j + 1;
}
}
thrust::host_vector<int> keys(s * m);
for (int i = 0; i < s; i++) {
for (int j = 0; j < m; j++) {
keys[i * m + j] = i;
}
}
thrust::device_vector<float> dev_in = par_in;
thrust::device_vector<int> dev_keys = keys;
auto t1 = std::chrono::high_resolution_clock::now();
test_seqScan(seq_in, s, m);
auto t2 = std::chrono::high_resolution_clock::now();
auto duration1 = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count();
std::cout << "Sequential duration: " << duration1 << "\n\n";
auto t3 = std::chrono::high_resolution_clock::now();
test_sumScan(dev_in, dev_keys, s, m);
auto t4 = std::chrono::high_resolution_clock::now();
auto duration2 = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count();
std::cout << "Parallel duration: " << duration2 << "\n\n";
}
My issue is that both these snippets of code take exactly the same amount of time to run regardless of how small or large I set s and m. I assume that I'm doing something wrong, but I don't know what; can anyone point out the issue?

how to fastly find array which include some numbers(1~255)?

I want to solve some algorithm problem.
Could you suggest any algorithms working more fast?
*Problem summary
- Find same array of key[200] is same as source array KEY[200]
- Each element of KEY[200] array is random numbers range 1~255
- only 2 file are given.
- You must implement just function find_array() of user_code.cpp
- It is not allowed to edit any other things
- You can use check() function for finding array
- test case is 50, time limit is 10 sec for 50 test case, memory limit is 256MB.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
extern void find_array(unsigned char key[200]);
unsigned char KEY[200];
int check(unsigned char key[200])
{
int pos = 0;
int equal = 0;
for (int c = 0; c < 200; c++)
{
if (key[c] == KEY[c])
pos++;
}
for (int c1 = 0; c1 < 200; c1++)
{
for (int c2 = 0; c2 < 200; c2++)
{
if(key[c1] == KEY[c2])
equal++;
}
}
return pos * 256 + equal;
}
int main()
{
for (int t = 0; t < 1; t++) //test case 50개
{
for (int i = 0; i < 200; i++)
{
KEY[i] = rand() % 255 + 1; //1~255
}
unsigned char key[200] = { 0, };
find_array(key); //you must implement this function
}
return 0;
}
//user_code.cpp
extern int check(unsigned char key[200]);
//you must implement this function
//below is my code take a long time(about 2sec for each case)
void find_array(unsigned char key[200])
{
unsigned char temp[200];
int result, pos, equal;
for (int k = 0; k < 200; k++)
temp[k] = 0;
for (int i = 0; i < 200; i++)
{
for (int val = 1; val <= 255; val++)
{
temp[i] = val;
result = check(temp);
equal = result % 256;
pos = (result - equal) / 256;
if (pos >= 1)
{
key[i] = val;
temp[i] = 0;
break;
}
}
}
}

when gray image width is 2048, 4096, running time of rotate 90 image is more longer than nearby

Now I am going to rotate image 90 degrees, the code is below, using openCV Mat struct.
And I found a phenomenon that when the image width is 4096 ,running time is about twice of running time of image width is 4097. Following is the running time output. Does somebody Know why?
#include<string>
#include<fstream>
#include<iostream>
#include "opencv.hpp"
using namespace cv;
void main()
{
std::string ImageFileName0 = "F:\\temp\\4096-3000.bmp";
std::string ImageFileName1 = "F:\\temp\\4097-3000.bmp";
Mat image4096 = imread(ImageFileName0);
Mat image4097 = imread(ImageFileName1);
int lWidth4096 = image4096.size().width;
int lHeight4096 = image4096.size().height;
Mat image4096Res(lWidth4096, lHeight4096, CV_8UC1);
for (int i=0; i<lHeight4096; i++)
{
for (int j=0; j<lWidth4096;j++)
{
image4096Res.at<uchar>(j, i) = 0;
}
}
int lWidth4097 = image4097.size().width;
int lHeight4097 = image4097.size().height;
Mat image4097Res(lWidth4097, lHeight4097, CV_8UC1);
for (int i = 0; i < lHeight4097; i++)
{
for (int j = 0; j < lWidth4097; j++)
{
image4097Res.at<uchar>(j, i) = 0;
}
}
for (int i = 0; i < 10; i++)
{
double time0 = static_cast<double>(getTickCount());
for (int j = 0; j < lWidth4096; ++j)
{
for (int i = 0; i<lHeight4096; ++i)
{
image4096Res.at<uchar>(j, i) = image4096.at<uchar>(i, j);
}
}
double time4096 = (static_cast<double>(getTickCount()) - time0) / getTickFrequency();
double time1 = static_cast<double>(getTickCount());
for (int j = 0; j < lWidth4097; ++j)
{
for (int i = 0; i<lHeight4097; ++i)
{
//srcTmp = srcimage.PointToRow(i);
//*(dstTmp + i) = srcimage.GetPixelValue(j, i);
image4097Res.at<uchar>(j, i) = image4097.at<uchar>(i, j);
}
}
double time4097 = (static_cast<double>(getTickCount()) - time1) / getTickFrequency();
std::cout << "4096 time:" << time4096*1000 << std::endl;
std::cout << "4097 time:" << time4097*1000 << std::endl;
std::cout << std::endl;
}
namedWindow("aa",CV_WINDOW_NORMAL);
imshow("aa", image4096Res);
waitKey();
}
Running time result:
4096 time:149.337
4097 time:56.8092
4096 time:143.556
4097 time:67.4758
4096 time:142.07
4097 time:58.2825
4096 time:153.973
4097 time:57.1894
4096 time:145.086
4097 time:58.7944
4096 time:156.33
4097 time:87.9404
4096 time:140.224
4097 time:56.9525
4096 time:144.413
4097 time:57.133
4096 time:141.672
4097 time:54.916
4096 time:148.443
4097 time:55.8449
Time consuming varies with the width of the image is here
It is clear that only when the image width is 1024,2048,4096 the execute time is abnormal, while the overall trend is increasing linearly.
Could you try using this version to see if the same difference exist
Also added test to see if loaded image is of type CV_8UC1.
Be aware that the result of your and my solution is a mirrored image
int lWidth4096 = image4096.size().width;
int lHeight4096 = image4096.size().height;
Mat image4096Res = cv::Mat::zeros(lWidth4096, lHeight4096, CV_8UC1);
int lWidth4097 = image4097.size().width;
int lHeight4097 = image4097.size().height;
Mat image4097Res = cv::Mat::zeros(lWidth4097, lHeight4097, CV_8UC1);
if (image4096.type() != CV_8UC1)
throw "need 8bit image as input";
if (image4097.type() != CV_8UC1)
throw "need 8bit image as input";
for (int i = 0; i < 10; i++)
{
double time0 = static_cast<double>(getTickCount());
for (int j = 0; j < lWidth4096; ++j)
{
uint8_t *buf = image4096Res.ptr(j);
for (int i = 0; i<lHeight4096; ++i)
{
//image4096Res.at<uchar>(j, i) = image4096.at<uchar>(i, j);
//buf[i] = image4096.at<uchar>(i, j);
buf[i] = (image4096.data + image4096.step[0] * i)[j];
}
}
double time4096 = (static_cast<double>(getTickCount()) - time0) / getTickFrequency();
double time1 = static_cast<double>(getTickCount());
for (int j = 0; j < lWidth4097; ++j)
{
uint8_t *buf = image4097Res.ptr(j);
for (int i = 0; i<lHeight4097; ++i)
{
//image4097Res.at<uchar>(j, i) = image4097.at<uchar>(i, j);
//buf[i] = image4097.at<uchar>(i, j);
buf[i] = (image4097.data + image4097.step[0] * i)[j];
}
}
double time4097 = (static_cast<double>(getTickCount()) - time1) / getTickFrequency();
std::cout << "4096 time:" << time4096 * 1000 << std::endl;
std::cout << "4097 time:" << time4097 * 1000 << std::endl;
std::cout << std::endl;
}

Resources