0

Needing help on best way to use 1 char array for mulitple user inputs, passing the user input data to a class setMethod(), then freeing up or reusing the same char array variable for the next user input statement, rinse and repeat. I know for pointers you can delete the memory address associated with them freeing up space, so I was thinking that would be my best bet?

// 9Application01.cpp
// Zachary James Mcclurg

#include "pch.h"
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

const int NAME_SIZE = 20;
const int STREET_SIZE = 30;
const int CITY_SIZE = 20;
const int STATE_CODE_SIZE = 3;
const int MAXINPUT = 80;

class Customer
{
private:
long customerNumber;
char custName[NAME_SIZE];
char streetAddress_1[STREET_SIZE];


public:
bool setNum(long num);
bool setName(char namesize[]);
bool setAddress1(char address1[]);


long getNum() const;
char* getName();
char* getAdd1();
};


bool Customer::setNum(long num)
{
if (num > 99999 || num < 0) {
        cout << "Invalid input. Re-enter ";
        return false;
}
customerNumber = num;
return true;
}

bool Customer::setName(char namesize[MAXINPUT])
{
if (strlen(namesize) >= NAME_SIZE) {
    cout << "Invalid input. Re-enter ";
    return false;
}

strcpy_s(custName, namesize);
return true;
}

 bool Customer::setAddress1(char address1[MAXINPUT])
{
if (strlen(address1) >= NAME_SIZE) {
    cout << "Invalid input. Re-enter ";
    return false;
}

strcpy_s(streetAddress_1, address1);
return true;
}



// Getter Methods 

long Customer::getNum() const
{
return customerNumber;
}

char* Customer::getName()
{
return custName;
}

char* Customer::getAdd1()
{
return streetAddress_1;
}


int main()
{
Customer custom;

char dataLine[MAXINPUT];
long numLine;


cout << "Name: ";
cin.getline(dataLine, MAXINPUT);
custom.setName(dataLine);

cout << "Customer ID: ";
cin >> numLine;
custom.setNum(numLine);

cout << "Primary Address: ";
cin.getline(dataLine, MAXINPUT);
custom.setAddress1(dataLine);


cout << "Your Name is: " << custom.getName() << endl;
cout << "Your Customer ID is: " << custom.getNum() << endl;
cout << "Your Primary Address is: " << custom.getAdd1() << endl;

}
Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
mjzach22
  • 29
  • 7

2 Answers2

0

The same character array may be used for multiple reads. No need for cleaning up as long as it is not dynamically allocated:

#include <iostream>

int main()
{
  char cstr[50];
  while(std::cin.getline(cstr, 50))
  {
    std::cout << "I read \"" << cstr << "\"" << std::endl;
  }

  return 0;
}

If the array were dynamically allocated (which it should be if the string is large enough to cause stack overflow), you would have to delete[] it once you are done:

#include <iostream>

int main()
{
  auto cstr = new char[50];
  while(std::cin.getline(cstr, 50))
  {
    std::cout << "I read \"" << cstr << "\"" << std::endl;
  }

  delete[] cstr;
  return 0;
}

But this code is dangerous. You might forget cleaning up or an exception somewhere in the middle might cause memory leak. You should consider std::string for maximum exception safety and it is easier to use too. std::string usually holds a pointer to dynamically allocated memory on the heap, and it is also in charge of cleaning it up once the string gets out of scope. That means you don't have to worry about managing memory / stack overflow and such. Here's an example:

#include <iostream>
#include <string>

int main()
{
  auto line = std::string(); // guaranteed to make no copies with C++17
  while(std::getline(std::cin, line))
  {
    std::cout << "I read \"" << line << "\"" << std::endl;
  }

  // No need to clean up manually!
  return 0;
}
Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
0

Reuse variables any time it makes sense to do so. Sometimes you will find that it's worth throwing away a few bytes in order to have nice readable names for your variables rather than using the same one in circumstances where its identifier no longer makes sense. Readable code is worth its KLOC in gold.

If you can't afford to waste memory, references can be used to assign a new name to an existing variable, but prefer the next option.

If you want a variable to go away when you are done with it, prefer an Automatic variable inside a narrower scope to a Dynamic allocation.

Example:

int main()
{
    int result;
    {

        char huge[102400]; // big 100k char array we don't want any longer than necessary
        // use huge array in computation of result
    } // huge array exits scope and is freed.
    // do stuff with result;
}

Because huge is an Automatic variable, it will be destroyed as soon as it exits its scope not matter how the scope is exited. This is hard to guarantee with a dynamic allocation. Millions and millions of programs written by millions and millions of programmers have shown that it is very easy to have an execution path that bypasses the delete. The only downside to huge is you have to keep an eye on the amount of Automatic storage available when writing the program.

Should stack space be an issue, then you dynamically allocate, but you make sure that the allocation is managed by a container object (A library container or a Smart Pointer) that is an Automatic variable.

user4581301
  • 33,082
  • 7
  • 33
  • 54