Issue in pointer while writing to file. segmentation fault - c++11

I am trying to write sequence of bytes into a binary file.
Converting structures into binary and storing in a pointer, and increment the pointer with the same size, before that i hold the address of that pointer into another so at the end i can write whole data from start to end into the file.
here is a code:
#include <stdio.h>
#include <iostream>
#include <string>
#include <fstream>
#include <cstring>
using namespace std;
struct OhlData_struct
{
int volume;
}__attribute__((__packed__));
struct StrCar
{
int PhoneNo;
long Model;
}__attribute__((__packed__));
int main()
{
StrCar Car;
OhlData_struct header;
char *Data=(char *)calloc(0,(sizeof(OhlData_struct) + (sizeof(StrCar) * 10)));
char *temp;
temp = Data;
string filename = "mydatastream_binary.txt";
ofstream outfile;
outfile.open (filename.c_str(), ios::out | ios::binary);
header.volume=123;
memcpy(Data,(char*) &header, sizeof(struct OhlData_struct));
Data += sizeof(struct OhlData_struct);
int i=0;
while(i <10)
{
Car.PhoneNo=101+i;
Car.Model=1001+i;
memcpy(Data,(char*) &Car, sizeof(struct StrCar));
outfile_copy.write (Data, sizeof(StrCar));
Data += sizeof(struct StrCar);
i++;
}
outfile.write (temp, (sizeof(struct OhlData_struct) + (sizeof(struct StrCar) * 10)));
cout << "\n\nFile writeing done\n\n";
outfile.write gives "sagmentation fault";
can anyone tell how to write whole DATA into the file ? where do I need to change the code!!
Tried a lot, but still not able to get the exact binary data into file,
I am new to C++ and this pointers are out of my mind.

Related

How to copy characters into string vector

Attempting to copy from a character vector to a string vector has been unsuccessful across multiple attempts at a solution
allocating memory to the vector prior to copying allows std::copy to work properly when placed at "OutputIterator result" (based on function template). I attempted:
std::copy(char1.begin(), char1.end(), v1.begin());
however, this was unsuccessful as well. using back_inserter returns error c2679 "binary '=': no operator found which takes a right-hand operand of type'char' (or there is no acceptable conversion).
input file is located here: https://adventofcode.com/2018/day/2
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstring>
#include <algorithm>
#include <iterator>
#include <cstdio>
int main() {
std::string field1;
std::string field2;
char characters;
std::vector<char>::iterator ptr;
std::vector<char>::iterator ptr2;
std::vector<char> char1;
std::vector<char> char2;
int size = 0;
std::ifstream inFile;
inFile.open("C:\\Users\\Administrator\\Desktop\\c++ files\\input2.txt");
if (!inFile) {
std::cout << "abort";
return 1;
}
while (inFile >> characters) { //read variables from input stream
char1.push_back(characters);
}
std::vector<std::string> v1(6500);
std::copy(char1.begin(), char1.end(), std::back_inserter(v1));
inFile.close();
return 0;
}
//26
expect vector v1 to hold values in vector char1. I am assuming the problem stems from the data type of v1 vs. char1, however, I have not been able to find a concrete solution. I do not want to read directly into a string vector; hence my current problem.
I am not sure what you try to achieve. Here few examples:
#include <string>
#include <vector>
int main()
{
std::string str1{ "Just for an example" }; // You can read it from a file
std::vector<std::string> vct_str1(32); // Lets say it has 32 std::string items
std::vector<std::string> vct_str2(32); // Lets say it has 32 std::string items
// **** A. Copy from std::string to std::vector<char>: ****
std::vector<char> vct_ch(str1.begin(), str1.end()); // On construction
// Or later: vct_ch.assign(str1.begin(), str1.end());
// **** B. Copy from std::vector<char> to std::string: ****
std::string str2(vct_ch.begin(), vct_ch.end()); // On construction
// Or later: str2.assign(vct_ch.begin(), vct_ch.end());
// **** C. Copy from std::vector<char> to std::vector<std::string>: ****
vct_str1[0].assign(vct_ch.begin(), vct_ch.end()); // Which is similar to B
// **** D. Source & Dest Types same as in Case-C But char per std::string: ****
int i = 0;
vct_str2.resize(vct_ch.size());
for (auto item : vct_ch)
vct_str2[i++] = item;
return 0;
}

Search Function returns wrong results

I have made a function for my program that reads from a text file, adds content to a vector and then search in that vector. The Problem is that even if the file is empty it shows that it found something, on the other side if i change return value to 0 it does not give results at all!
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <algorithm>
using namespace std;
vector<string> contacts;
//This function returns at what index the name is found
int searchContact(string contactToSearch)
{
string entry;
ifstream input;
input.open("contacts.txt");
while (input.good())
{
while (getline(input, entry))
{
contacts.push_back(entry);
}
input.close();
}
for(int i = 0; i < contacts.size(); i++)
{
if(contactToSearch == contacts[i])
{
//Found => Returning index rest of program can see index
return i;
}
}
return 1;
}
I have just refactored your code a little. Further improvements are possible, but to begin with
1) You dont need a while for input.good()
2) You were trying to return 0 and 1 which are indeed valid positions where the string could have been present in the vector
All these aside, I still think your code might not properly populated the array The reasons for this maybe :- case sensitive comparison, reading incorrect file, binary file.. etc..
Here is a refactored code that you could use
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <algorithm>
using namespace std;
void readContacts(const string &fileName inputFileName, vector<string> &contacts){
string entry;
ifstream input;
input.open(inputFileName);
if (input.good())
{
while (getline(input, entry))
contacts.push_back(entry);
input.close();
}
}
int searchContact(const string &contactToSearch, vector<string> &contacts)
{
for (int i = 0; i < contacts.size(); i++)
{
if (contactToSearch == contacts[i])
return i;
}
return -1;
}
int main(){
vector<string> contacts;
// This needs to be filled in with the contact name u want to search
string contactToSearch;
readContacts("contacts.txt", contacts);
int index = searchContact(contactToSearch, contacts)
if (index != -1)
cout << "Found Contact " << contactToSearch" at location " << index << endl;
else
cout << "Could Not find contact " << contactToSearch << endl;
}

How to use copy_to_user

I'm trying to add a custom system call into the linux kernel. Here is a simple code:
#include <linux/mysyscall.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>
#include <asm/system.h>
asmlinkage int sys_mysyscall(int *data){
int a = 3;
cli();
copy_to_user(data, &a, 1);
sti();
printk(KERN_EMERG "Called with %d\n", a);
return a;
}
I can compile a kernel with mysyscall added and when I try to access it with a user program like:
#include <linux/mysyscall.h>
int main(void){
int *data;
int r;
int a = 0;
data = &a;
r = mysyscall(data);
printf("r is %d and data is %d", r, *data);
}
*data does not equal to 3 it equals to 0.
How should I use copy_to_user to fix it?
The copy to user line of code copies only one byte from 'a'. In case of little endian systems it is going to be 0. Copy all the 4 bytes to get the correct result.

fftw3 proper using

#include <stdio.h>
#include <Windows.h>
#include <string.h>
#include <stdlib.h>
#include "fftw3.h"
int main(void)
{
FILE *fp;
int rozmiar_pliku;
char standard[5] = {0};
char format[5] = {0};
int samplerate;
int k,i;
fftw_complex in[128];
fftw_complex out[128];
fftw_plan p;
fp = fopen("Kalimba.wav","rb" );
//printf("%d\n",fp);
if (fp)
{
fread(standard,1,4,fp);
printf("%s\n",standard);
printf("RIFF\n");
if (!strcmp(standard,"RIFF" ))
{
fread(&rozmiar_pliku,4,1,fp);
printf("size: %d\n", rozmiar_pliku);
}
fread(format,1,4,fp);
printf("format: %s\n",format);
fseek(fp,24,SEEK_SET);
fread(&samplerate,1,4,fp);
printf("sample rate: %d\n",samplerate);
fseek(fp,44,SEEK_SET);
for(i=0;i<128;++i)
{
in[i][0]=getc(fp);
in[i][1]=in[i][0];
}
/*
p = fftw_plan_dft_1d(128, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
fftw_execute(p);
for(int j=0;j<128;++j)
printf("%lf+i*%lf",out[j][0],out[j][1]);
fftw_destroy_plan(p);
fftw_free(in);
fftw_free(out);
*/
}
return 0;
}
I'm trying to read wave file and perform FFT by using FFTW3. If i uncomment part which is commented there's nothing show on screen. If I leave it commented :
RIFF
RIFF
size: 61392422
format: WAVE
sample rate: 44100
If uncommented nothing appears. I don't know why it is going like this. Any use of fftw3 cause this situation.
in and out are statically declared arrays. Try passing &in[0] and &out[0] to match the type expected by fftw_plan_dft_1d.
As it is recommended in the documentation, you should declare in and out using fftw_malloc.
You can allocate them in any way that you like, but we recommend using fftw_malloc.
Then, you'll need to initialize in after creating the plan.
You must create the plan before initializing the input, because FFTW_MEASURE overwrites the in/out arrays. (Technically, FFTW_ESTIMATE does not touch your arrays, but you should always create plans first just to be sure.)
The result with some other modifications, is
#include <stdio.h>
#include <stdlib.h>
#include "fftw3.h"
int main(void)
{
FILE *fp;
int rozmiar_pliku;
char standard[5] = {0};
char format[5] = {0};
int samplerate;
int i;
fftw_complex *in, *out;
fftw_plan p;
fp = fopen("audioFile1.wav","rb" );
if (fp)
{
fread(standard,1,4,fp);
printf("%s\n",standard);
printf("RIFF\n");
if (!strcmp(standard,"RIFF" ))
{
fread(&rozmiar_pliku,4,1,fp);
printf("size: %d\n", rozmiar_pliku);
}
fread(format,1,4,fp);
printf("format: %s\n",format);
fseek(fp,24,SEEK_SET);
fread(&samplerate,1,4,fp);
printf("sample rate: %d\n",samplerate);
fseek(fp,44,SEEK_SET);
// Allocate in and out buffers using fftw_alloc
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * 128);
out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * 128);
// Create plan before initializing in
p = fftw_plan_dft_1d(128, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
// Initialize in after creating plan
for(i=0;i<128;++i)
{
in[i][0]=getc(fp);
in[i][1]=in[i][0];
}
fftw_execute(p);
for(int j=0;j<128;++j)
printf("%lf+i*%lf\n",out[j][0],out[j][1]);
fftw_destroy_plan(p);
fftw_free(in); fftw_free(out);
}
return 0;
}

OpenCV: Load multiple images

I am updating some older OpenCV code that was written in (I guess) an OpenCV 1.1 manner (i.e. using IplImages).
What I want to accomplish right now is to simply load a series of images (passed as command line arguments) as Mats. This is part of a larger task. The first code sample below is the old code's image loading method. It loads 5 images from the command line and displays them in sequence, pausing for a key hit after each, then exits.
The second code sample is my updated version using Mat. It works fine so far, but is this the best way to do this? I've used an array of Mats. Should I use an array of pointers to Mats instead? And is there a way to do this such that the number of images is determined at run time from argc and does not need to be set ahead of time with IMAGE_NUM.
Basically, I'd like to be able to pass any number (within reason) of images as command line arguments, and have them loaded into some convenient array or other similar storage for later reference.
Thanks.
Old code:
#include <iostream>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
using namespace std;
using namespace cv;
// the number of input images
#define IMAGE_NUM 5
int main(int argc, char **argv)
{
uchar **imgdata;
IplImage **img;
int index = 0;
char *img_file[IMAGE_NUM];
cout << "Loading files" << endl;
while(++index < argc)
if (index <= IMAGE_NUM)
img_file[index-1] = argv[index];
// malloc memory for images
img = (IplImage **)malloc(IMAGE_NUM * sizeof(IplImage *)); // Allocates memory to store just an IplImage pointer for each image loaded
imgdata = (uchar **)malloc(IMAGE_NUM * sizeof(uchar *));
// load images. Note: cvLoadImage actually allocates the memory for the images
for (index = 0; index < IMAGE_NUM; index++) {
img[index] = cvLoadImage(img_file[index], 1);
if (!img[index]->imageData){
cout << "Image data not loaded properly" << endl;
return -1;
}
imgdata[index] = (uchar *)img[index]->imageData;
}
for (index = 0; index < IMAGE_NUM; index++){
imshow("myWin", img[index]);
waitKey(0);
}
cvDestroyWindow("myWin");
cvReleaseImage(img);
return 0;
}
New code:
#include <iostream>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <time.h>
using namespace std;
using namespace cv;
// the number of input images
#define IMAGE_NUM 5
int main(int argc, char **argv)
{
Mat img[IMAGE_NUM];
int index = 0;
for (index = 0; index < IMAGE_NUM; index++) {
img[index] = imread(argv[index+1]);
if (!img[index].data){
cout << "Image data not loaded properly" << endl;
cin.get();
return -1;
}
}
for (index = 0; index < IMAGE_NUM; index++) {
imshow("myWin", img[index]);
waitKey(0);
}
cvDestroyWindow("myWin");
return 0;
}
you can use a vector instead of an array:
for example
#include <iostream>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <time.h>
#include <vector>
using namespace std;
using namespace cv;
int main(int argc, char **argv)
{
vector<Mat> img;
//Mat img[IMAGE_NUM];
int index = 0;
for (index = 0; index < IMAGE_NUM; index++) {
//img[index] = imread(argv[index+1]);
img.push_back(imread(argy[index+1]));
if (!img[index].data){
cout << "Image data not loaded properly" << endl;
cin.get();
return -1;
}
}
vector<Mat>::iterator it;
for (it = img.begin(); it != img.end() ; it++) {
imshow("myWin", (*it));
waitKey(0);
}
cvDestroyWindow("myWin");
return 0;
}
It took me a while to get back around to this, but what I've ended up doing is as follows, which is probably functionally the same as Gootik's suggestion. This has worked well for me. Notice that for functions that take Mat& (i.e. a single cv::Mat), you can just de-ref the array of Mats and pass that, which is a notation I'm more comfortable with after doing a lot of image processing work in Matlab.
#include <iostream>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
using namespace std;
using namespace cv;
int main(int argc, char **argv)
{
if (argc==1){
cout << "No images to load!" << endl;
cin.get();
return 0;
}
int index = 0;
int image_num = argc-1;
Mat *img = new Mat[image_num]; // allocates table on heap instead of stack
// Load the images from command line:
for (index = 0; index < image_num; index++) {
img[index] = imread(argv[index+1]);
if (!img[index].data){
cout << "Image data not loaded properly" << endl;
cin.get();
return -1;
}
}
for (index = 0; index < image_num; index++) {
imshow("myWin", img[index]);
waitKey(0);
}
cvDestroyWindow("myWin");
delete [] img; // notice the [] when deleting an array.
return 0;
}

Resources