d2jsp
Log InRegister
d2jsp Forums > Off-Topic > Computers & IT > Programming & Development > C++ Question
Add Reply New Topic New Poll
Trade Moderator
Posts: 26,719
Joined: Dec 20 2005
Gold: 82,000.00
Trader: Trusted
Sep 10 2019 08:47am
So I have this assignment to create an array of class with dynamic memory.
Problem is that every time I try to get input from the user inside a for loop, I get memory error
Here's the code itself with comments aswell so you will understand what I'm aiming to do in each line
Code
#include <iostream>
#include <cstdlib>
#include <cstring>

using namespace std;
#pragma warning(disable : 4996)


class Web {
private:
char *webName;
char *webLink;
char *webDesc;

public:
Web();
Web(char * ,char * ,char *);
~Web();

void setWeb(char *,char *,char *);
char getWeb(char * ,char *,char *);
void displayWeb();

};
// Empty Constructor
Web::Web() { webName=NULL,webLink=NULL,webDesc=NULL; }
// Full Constructor
Web::Web(char *w, char *l, char *d) { strcpy(webName, w); strcpy(webLink, l); strcpy(webDesc, d); }
Web::~Web() {}

// Getters & Setters
void Web::setWeb(char *w, char*l, char *d) { strcpy(webName, w); strcpy(webLink, l); strcpy(webDesc, d); }
char Web::getWeb(char *,char *,char *) { return *webName; return *webLink; return *webDesc; }

// Display
void Web::displayWeb() { cout << "Webname is: " << " Url: " << " Description: " << getWeb(webName,webLink,webDesc) << endl; }


int main() {

// Declaring variables
char *name = NULL;
char *link = NULL;
char *desc = NULL;
int webInsertNumber = 0;

// Receiving amount of website to enter
cout << "Enter amount of website you wish to add:";
cin >> webInsertNumber;
// Allocate array of class of size recieived before
Web *arr;
arr= new (nothrow) Web[webInsertNumber];
if (arr == nullptr) {
cout << "Memory problems :(" << endl;
}
else {
for (int i = 0; i < webInsertNumber; i++)
{
// Enter each input to a variable
cout << "Enter Web name: ";
cin >> name;
cout << "Enter URL: ";
cin >> link;
cout << "Enter Description: ";
cin >> desc;
// Calling function to set variable to array
arr->setWeb(name, link, desc);
// Move pointer by one
arr++;
}
}
return 0;
}


Thanks in advance :)
Member
Posts: 13,958
Joined: Dec 9 2007
Gold: 320.00
Trader: Trusted
Sep 10 2019 10:33am
char *name = NULL;
cin >> name;

This is the problem. You try to store the input to a NULL memory slot. You need to allocate memory for the variables "name", "link" and "desc" in order to store the input.
The correct way of allocating memory (static memory) on the stack would be:

Code
char str[15];
cout << "enter a string";
cin >> str;


This creates a char array of 16 chars (starting from 0). However, this will become a problem later on since it will become a dangling pointer when you string-copy the variables (in your constructor).
To fix that, you need to first allocate the memory needed on the heap (dynamic memory) using malloc.
An example of that would be:

Code
char *name = (char *)malloc(sizeof(char)*100+1);
char *link = (char *)malloc(sizeof(char)*100+1);
char *desc = (char *)malloc(sizeof(char)*100+1);


This will allocate memory for a 101 bytes. Since 1 char is 1 byte, you need 100 bytes to store a 100 byte string. This will allow you to store a string consisting of 100 chars.
Note that when you ask for user input, an extra invisible char will be added to the output string which is called the null terminator (which marks the end of a string) and has the size of 1 char.
You need to allocate memory for that null terminator as well, which results in allocating memory for an extra char, aka 101 chars. If you are unsure, just allocate more memory than necessary.

Now that you have allocated your memory on the heap, you can just dereference the pointer instead of using strcpy in your class "Web". This means that you can just point the memory that you have allocated for the variable "name" in the main() function to the variable "name" in your class "Web".

However, for the next iteration, you will overwrite the data since you haven't allocated more memory for the new input. You need to allocate memory in every iteration instead (or on the stack at first, and store it in the heap in the constructor)
You can worry about freeing memory later on once you understand how the stack/heap works and once you've figured out how pointers work. :)

This post was edited by Xaysia on Sep 10 2019 10:58am
Trade Moderator
Posts: 26,719
Joined: Dec 20 2005
Gold: 82,000.00
Trader: Trusted
Sep 10 2019 11:50pm
Quote (Xaysia @ Sep 10 2019 07:33pm)
char *name = NULL;
cin >> name;

This is the problem. You try to store the input to a NULL memory slot. You need to allocate memory for the variables "name", "link" and "desc" in order to store the input.
The correct way of allocating memory (static memory) on the stack would be:

Code
char str[15];
cout << "enter a string";
cin >> str;


This creates a char array of 16 chars (starting from 0). However, this will become a problem later on since it will become a dangling pointer when you string-copy the variables (in your constructor).
To fix that, you need to first allocate the memory needed on the heap (dynamic memory) using malloc.
An example of that would be:

Code
char *name = (char *)malloc(sizeof(char)*100+1);
char *link = (char *)malloc(sizeof(char)*100+1);
char *desc = (char *)malloc(sizeof(char)*100+1);


This will allocate memory for a 101 bytes. Since 1 char is 1 byte, you need 100 bytes to store a 100 byte string. This will allow you to store a string consisting of 100 chars.
Note that when you ask for user input, an extra invisible char will be added to the output string which is called the null terminator (which marks the end of a string) and has the size of 1 char.
You need to allocate memory for that null terminator as well, which results in allocating memory for an extra char, aka 101 chars. If you are unsure, just allocate more memory than necessary.

Now that you have allocated your memory on the heap, you can just dereference the pointer instead of using strcpy in your class "Web". This means that you can just point the memory that you have allocated for the variable "name" in the main() function to the variable "name" in your class "Web".

However, for the next iteration, you will overwrite the data since you haven't allocated more memory for the new input. You need to allocate memory in every iteration instead (or on the stack at first, and store it in the heap in the constructor)
You can worry about freeing memory later on once you understand how the stack/heap works and once you've figured out how pointers work. :)


So basically I needed to allocate the size of the actual string I'm going to receive as input from the user on each variable ( name,link,desc ) right?
Should I do this on every iteration of the for loop or lets say I decide on the maximum size once and that's it?

I don't mind override the data stored in those variables as I'm going to store them in the class called Web and using the function setWeb(); to allocate the memory.
but if I need to allocate the memory for each variable in main, shouldn't I do the same in the function aswell?

Thanks :)
Member
Posts: 13,958
Joined: Dec 9 2007
Gold: 320.00
Trader: Trusted
Sep 11 2019 06:01am
Quote (Yakir @ 11 Sep 2019 07:50)
So basically I needed to allocate the size of the actual string I'm going to receive as input from the user on each variable ( name,link,desc ) right?
Should I do this on every iteration of the for loop or lets say I decide on the maximum size once and that's it?

I don't mind override the data stored in those variables as I'm going to store them in the class called Web and using the function setWeb(); to allocate the memory.
but if I need to allocate the memory for each variable in main, shouldn't I do the same in the function aswell?

Thanks :)


Yes. You need to allocate the memory for the variables that will store the input from the console. Either dynamically (char *a = malloc()) or statically (char a[len]). What you choose to do doesn't really matter.
The important thing is that you allocate memory dynamically in your class (using malloc), since this data will be "saved" and should not be overwritten.

In main(), you can allocate new space every iteration, but it's less overhead to just allocate once and then overwrite the data in the variables in main() rather than allocating and freeing every iteration.

No problems bud :)
Trade Moderator
Posts: 26,719
Joined: Dec 20 2005
Gold: 82,000.00
Trader: Trusted
Sep 12 2019 05:51am
Quote (Xaysia @ Sep 11 2019 03:01pm)
Yes. You need to allocate the memory for the variables that will store the input from the console. Either dynamically (char *a = malloc()) or statically (char a[len]). What you choose to do doesn't really matter.
The important thing is that you allocate memory dynamically in your class (using malloc), since this data will be "saved" and should not be overwritten.

In main(), you can allocate new space every iteration, but it's less overhead to just allocate once and then overwrite the data in the variables in main() rather than allocating and freeing every iteration.

No problems bud :)


So how should I allocate the memory of the array storing the class?
Code
// Receiving amount of website to enter
cout << "Enter amount of website you wish to add:";
cin >> webInsertNumber;
// Allocate array of class of size recieived before
Web *arr;
arr= new (nothrow) Web[webInsertNumber];
if (arr == nullptr) {
cout << "Memory problems :(" << endl;
}
else {


I want to have X number of stored information on each web depends on the size of the input the user entered.
I thought by new I will be able to do it but I can't move the pointer to the second position and then getting the same memory error.
Trade Moderator
Posts: 26,719
Joined: Dec 20 2005
Gold: 82,000.00
Trader: Trusted
Sep 18 2019 02:21am
I figured the whole program issue.
Instead of calling to arr->setWeb();
I should have do arr = new Web()

:)
Trade Moderator
Posts: 21,403
Joined: Jul 26 2006
Gold: 2,739.00
Trader: Mediator
Sep 18 2019 06:02pm
Quote (Yakir @ Sep 10 2019 10:47am)
So I have this assignment to create an array of class with dynamic memory.
Problem is that every time I try to get input from the user inside a for loop, I get memory error
Here's the code itself with comments aswell so you will understand what I'm aiming to do in each line
Code
#include <iostream>
#include <cstdlib>
#include <cstring>

using namespace std;
#pragma warning(disable : 4996)


class Web {
private:
char *webName;
char *webLink;
char *webDesc;

public:
Web();
Web(char * ,char * ,char *);
~Web();

void setWeb(char *,char *,char *);
char getWeb(char * ,char *,char *);
void displayWeb();

};
// Empty Constructor
Web::Web() { webName=NULL,webLink=NULL,webDesc=NULL; }
// Full Constructor
Web::Web(char *w, char *l, char *d) { strcpy(webName, w); strcpy(webLink, l); strcpy(webDesc, d); }
Web::~Web() {}

// Getters & Setters
void Web::setWeb(char *w, char*l, char *d) { strcpy(webName, w); strcpy(webLink, l); strcpy(webDesc, d); }
char Web::getWeb(char *,char *,char *) { return *webName; return *webLink; return *webDesc; }

// Display
void Web::displayWeb() { cout << "Webname is: " << " Url: " << " Description: " << getWeb(webName,webLink,webDesc) << endl; }


int main() {

// Declaring variables
char *name = NULL;
char *link = NULL;
char *desc = NULL;
int webInsertNumber = 0;

// Receiving amount of website to enter
cout << "Enter amount of website you wish to add:";
cin >> webInsertNumber;
// Allocate array of class of size recieived before
Web *arr;
arr= new (nothrow) Web[webInsertNumber];
if (arr == nullptr) {
cout << "Memory problems :(" << endl;
}
else {
for (int i = 0; i < webInsertNumber; i++)
{
// Enter each input to a variable
cout << "Enter Web name: ";
cin >> name;
cout << "Enter URL: ";
cin >> link;
cout << "Enter Description: ";
cin >> desc;
// Calling function to set variable to array
arr->setWeb(name, link, desc);
// Move pointer by one
arr++;
}
}
return 0;
}


Thanks in advance :)



I think it needs to go to a new web. Try changing the arr out

Edit: nvm you swapped it out and got it lol - should of kept reading

This post was edited by Sn0 on Sep 18 2019 06:03pm
Go Back To Programming & Development Topic List
Add Reply New Topic New Poll