I'm learning C++ by reading forums and books so I'm kind of new to the programmer's world.
So please don't hesitate to improve my code because I'm eager to learn !
I'm having a problem to access an array of structure that I passed to a function.
Here's my code :
struct Comber
{ double real;
double im;
double mod;
};
int main (void)
{
struct Comber *Nmbr=NULL; //Nmbr Initialised for passing to Read where it's re-declared
int N;
Read(Nmbr, N);
Module(Nmbr, N);
}
void Read (Comber *Nmbr, int &N)
{
cout<<"\nHow many of those numbers do you have ?\t";
cin>>N;
Nmbr = new struct Comber [N];
for(int i=0;i<=N;i++)
{
cout<<"#"<<i<<"\nreal :\t";
cin>>Nmbr[i].real;
cout<<"img :\t";
cin>>Nmbr[i].im;
cout<<"-----"<<endl;
}
}
void Module (Comber *Nmbr, const int &N)
{
for(int i=0;i<N;i++)
{
//Here's where my problem is at.
Nmbr[i].mod=sqrt(pow(Nmbr[i].real,2)+pow(Nmbr[i].im,2));
}
}
I get an access violation because there's either no data stored or I'm looking at the wrong place. (right ?)
So I'm wondering whether the mistake is in Read or in Module and what actually is.
Thanks for looking into it !
If you want to change the value of the Nmbr pointer, you need to pass it by reference or pointer, not by value. Like this:
void Read (Comber *&Nmbr, int *N)
With your code Nmbr in the main is not chaged.
Related
Our teacher told us to create a vector of objects and perform operations on it, but I couldn't understand how to properly do that: I tried to make a simple project with minimum data so that I could know what I was doing.
I have this class
class Obj {
private:
int num;
public:
Obj();
void setNum(int nuovo_num);
int getNum();
};
And then this one, with a vector of Obj
class VettObj{
private:
vector<Obj> vett;
public:
VettObj();
void setVett();
void stampaVett();
};
My initial thought was to use an iterator but I was just making a total mess and, with almost useless research, I decided to use a common integer counter.
I found that I shouldn't write anything in the VettObj costructor, as it automatically initialize stuff, so I left it blank.
The method that adds elements is this
void VettObj::setVett(){
Obj temp;
int i;
i = 0;
while(i < 5){
temp.setNum(10);
vett.push_back(temp);
i++;
}
}
And the one that prints elements
void VettObj::stampaVett(){
int i;
i = 0;
while(i < 5){
vett[i].getNum();
i++;
}
}
When I compile, everything goes well, but when I run the program I get nothing on the screen. I don't want to use mostly vector functions(if not necessary) as I saw that a lot of people can do it like this. I would really like to know how to do it with iterators too. Help pls ????
You are not actually printing anything in the stampaVett() method.
You could try with:
void VettObj::stampaVett(){
int i = 0;
while (i < 5){
std::cout << vett[i].getNum();
i++;
}
}
I'd also suggest using English for method or variable instead of Italian, since SO is an international community.
I am trying to pass a structure I created in a function to another function so basically what im trying to do is dynamically create the amount of structures needed the amount of structures is in a text file so in the text file there would be a number like 5 and and 5 data sets. I want to pass the structures I created in my function to another function. I started programming a few months ago so forgive me if there is a simple solution or if this question has been asked.
struct graph
{
int Max,Min,index;
double dataArray[300];
};
void readfile()
{
int amount;
char tmpSTR,nmbrGraph;
ifstream myFile("data1.txt",ios::in);
myFile>>amount;
myFile>>tmpSTR;
myFile>>nmbrGraph;
graph* Data = new graph[amount];
for(int j=0;j<nmbrGraph;j++)
{
for(int i=0;i<299;i++)
myFile>>Data[j].dataArray[i];
}
//hOW WOULD I PASS THE STRUCTURE "DATA" TO THE FUNCTION anotherFunction?
}
void anotherFunction()
{
for(int i = 0;i<300;i++)
cout<<Data[scroll].dataArray[i])<<endl; /*Error here! scroll being an
integer declared globally*/
}
Pass the graph* pointer by value or reference to anotherFunction as an argument. Also, it is important to include the number items, as that was determined by reading the file and not knowable beforehand.
// by value
void anotherFunction(graph* Data, int amount);
// by reference
void anotherFunction(graph*& Data, int amount);
I want to use polymorphism and create objects outside of main or any other function so that the functions are independent of the type of the objects I have. My code is as follows:
The main class:
class load{ //Main class
protected:
static load **L;
static int n, n1;
public:
load(){};
virtual float getpower()=0;
static int getn();
static load ** getL();
};
load **load::L;
int load::n;
int load::n1;
int load::getn(){
return n;
}
load** load::getL(){
return L;
}
The child class:
class load1:public load{
private:
float power;
public:
load1();
load1(int s);
void createUnits1();
float getpower();
}l1(0); //Object creation
load1::load1(int s){
createUnits1();
}
void load1::createUnits1(){
cout<<"Give the number of type 1 objects: "<<endl;
cin>>n1;
for (int i=0;i<n1;i++){
load1 temp; //Run default constructor
}
}
load1::load1(){
cout<<"Give the power of the device: "<<endl;
cin>>power;
n++;
if (n==1){
L=(load **)malloc(n*sizeof(load *));
}
else {
L=(load **)realloc(L,n*sizeof(load *));
}
L[n-1]=this;
}
float load1::getpower(){
return power;
}
The function of calculation:
float get_total_P(load **l, int num){
float tot_power=0;
for(int i=0;i<num;i++){
tot_power+=l[i]->getpower();
}
return tot_power;
}
My main function:
int main() {
load **l;
int num;
num=load::getn();
l=load::getL();
float total_P=get_total_P(l, num);
cout<<total_P;
return 0;
}
The upper code produces a segmentation fault but I can't see the reason why. The segmentation fault is on the line
tot_power+=l[i]->getpower();
So I guess my way of creating objects is wrong. Is there a better way to do this?
The reason for your segfault, is that l doesn't point to anything valid !
In main() you initialise l with load::getL(). But this function only returns the load::L which has the same type and was defined as static in your load class but was never initialized.
You have coded in your derived class load1 some initialisation code for L, but it is never invoqued in main().
Your code has also some severe design issues:
It's not advised to use malloc() and realloc() in C++ code. If you create an object in C++ use new. If you want some dynamic array, use vectors.
You could get L and hence l initialized if you'd create some load1 objects before calling getL(). But due to your realloc, l would then risk to point to an obsolete thus invalid address, if you would create any other load1 object before calling get_total().
It's bad practice and terrible design to request user input in a constructor. The constructor is meant to cosntruct an object with the parameters you give him when you call him. Imagine the user would give an invalid parameter ? The user would be asked for input whenever a load1 object is constucted. Even for temporary variables, not even speaking from the effect when you'd write load1 a[10];
I am new to C++ and there is a basic problem I am dealing with. The code below gives complier error:
#include <iostream>
using namespace std;
struct contact_info {
long number;
string name;
};
contact_info take(){
contact_info takein[2];
for (int i=0; i<2; i++) {
cout<<"what is the name"<<"\n";
getline(cin,takein[i].name);
cout<<"what is the phone number"<<"\n";
cin>>takein[i].number;
};
return takein;
};
void give(contact_info takein){
cout<<"Name:"<<takein.name<<"\n"<<"Number:"<<takein.number;
};
int main(int argc, const char * argv[])
{
contact_info takein;
takein=take();
give(takein);
return 0;
}
The error comes from function "take" and is "No viable conversion from 'contact_info[2]' to 'contact_info'"
The code is supposed to take two contact informations in a loop and then prints them on the screen.
I think I need to use pointers for that to pass the "takein" from "take" function to "main" function. Can anyone says if I can fix the code using array and not pointer?
#include <iostream>
struct contact_info
{
long number;
string name;
};
void take(contact_info takein[2])
{
for (int i=0; i<2; i++)
{
cout<<"what is the name"<<"\n";
getline(cin,takein[i].name);
cout<<"what is the phone number"<<"\n";
cin>>takein[i].number;
};
};
void give(contact_info takein)
{
cout<<"Name:"<<takein.name<<"\n"<<"Number:"<<takein.number;
};
int main()
{
contact_info takein[2];
take(takein);
for(int i=0;i<2;++i)
give(takein[i]);
return 0;
}
return takein;
but
contact_info takein[2];
Compiler is upset because you're trying to return an array, use return takin[0]; or return takin[1]; to return a specific contact_info
Addendum
Don't be afraid to learn Python first, higher level languages are a lot more forgiving and python is by no means a toy language, Python and C++ are two things I use daily and I love them both. I tolerate Java, it can be good when you want static typing and something more forgiving than C++, or in my case Android :P
If you edit your question to describe what you want to do I am happy to provide some annotated code to demonstrate, leave a comment to this to get my attention.
contact_info[] take(){
...
}
if you are trying to return an array.
for returning an element, use
return takein[0];
or
return takein[1];
If your goal is "to take two contact informations in a loop and then prints them on the screen", you must pass an array to get information and pass an array to prints it:
contact_info * take(contact_info *takein){
for (int i=0; i<2; i++) {
cout<<"what is the name"<<"\n";
getline(cin, takein[i].name);
cout<<"what is the phone number"<<"\n";
cin>>takein[i].number;
};
return takein;
};
void give(contact_info * takein){
for (int i = 0; i < 2; i++)
cout<<"Name:"<<takein[i].name<<"\n"<<"Number:"<<takein[i].number;
};
int main(int argc, const char * argv[])
{
contact_info takein[2];
// pass takein as an array
take(takein);
give(takein);
return 0;
}
Secret's out! Arrays are pointers. Or at least, they implicitly convert to them. Even it you did have the right type, you'd be using undefined behavior, as the array is allocated on a place on the stack that no longer exists.
I'll assume you actually want to 'return two things', otherwise Alec's answer is perfectly valid.
Try a vector, or a 2 element struct. People often struggle mentally with the notion of creating a struct only to serve as a return value, but it's worth it from a maintainability standpoint. You get the power of naming the type and naming its contents, and that self-documents your intent.
In the main function takein is a variable of type contact_info
and here takein=take(); you are trying assign an array to a normal variable.
Suppose I have a struct and a file with binary representations of those structs and I'll make a function/method that access this binary data using ifstream::read().
Here's an example struct:
struct MyStruct {
int x; //Value interested in
int y; //Value interested in
int anotherInteger; //Not interested
double aDouble; //Not interested
}
How do I make the function (I'll call it here readData) either: not using pointers when reading or, if using pointers is necessary, where would I put the proper delete?
So far, the relevant part of my readData looks like this:
void readData(int position, int &returnX, int &returnY) {
ifstream inFile("binaryFile.dat",ios::binary);
MyStruct *st = new MyStruct[1];
inFile.seekg(sizeof(MyStruct)*pos);
inFile.read((char*) st, sizeof(MyStruct));
returnX = st[0].x;
returnY = st[0].y;
//delete [] st goes here?
}
I've tried uncommenting the delete part, but I get an allocation error, probably because the values of x and y are pointing to something that doesn't exist anymore.
Any ideas on how to solve this?
Why wouldn't you use a local variable?
void readData(int position, int &returnX, int &returnY) {
ifstream inFile("binaryFile.dat",ios::binary);
inFile.seekg(sizeof(MyStruct)*position);
MyStruct st;
inFile.read((char*) &st, sizeof(MyStruct));
returnX = st.x;
returnY = st.y;
}
int main() {
int mainx, mainy;
readData(0, mainx, mainy);
return 0;
}
Also, references cannot be re-seated. Therefore the assignment assigns the value to the origional int passed by the calling function. returnX and returnY are not pointed at the local variables. In the code above, the assignment changes mainx and mainy.
The simpler way it's to use a local variable:
void readData(int position, int &returnX, int &returnY) {
ifstream inFile("binaryFile.dat",ios::binary);
MyStruct st;
inFile.seekg(sizeof(MyStruct)*position);
inFile.read((char*)&st, sizeof(MyStruct));
returnX = st.x;
returnY = st.y;
}
The delete[] is fine. If you get an error, it's not because the values of x and y are pointing to something that doesn't exist anymore since their values are just integers and don't point to anything.