1

Say I have a variable

std::string str; // initialized with some value

And a struct defined as:

struct test
    {
    public:
        const char* name;
    };

I know this can be done :

test t1;

t1.name = str.c_str();

But this will store the address of the variable str in t1.name

Instead I want the values of str to put in a char array member of the structure which should be of exact same size as variable str.

Is there a way that can be achieved or a better design

Thanks in advance!

Vishal Khemani
  • 171
  • 2
  • 13
  • 4
    Why cant you use `std::string` ? – kocica Sep 06 '17 at 20:39
  • 5
    Just store a `std::string` and you will save yourself **tons** of trouble. – Bo Persson Sep 06 '17 at 20:41
  • 4
    *"Is there a way that can be achieved or a better design"* A better design would be to make `test::name` a `std::string`. – François Andrieux Sep 06 '17 at 20:45
  • 1
    Your pointer may not be valid after `str` is modified. From CppReference: The pointer obtained from c_str() may be invalidated by: Passing a non-const reference to the string to any standard library function, or valling non-const member functions on the string, excluding operator[], at(), front(), back(), begin(), rbegin(), end() and rend(). Writing to the character array accessed through c_str() is undefined behavior. – Thomas Matthews Sep 06 '17 at 20:47

2 Answers2

0

But this will store the address of the variable str in t1.name

Not exactly. str.c_str() does not return the address of variable str. It returns the address of the character array owned by str.

Instead I want the values of str to put in a char array member of the structure

To do that, the structure must have a char array member. Your structure does not; it has a pointer member.

char array member of the structure which should be of exact same size as variable str.

This is not possible. The size of the string is dynamic i.e. it may change at run time. The size of a member array must be known at compile time.

You can instead allocate an array dynamically. As the name implies, the size of dynamic allocation may be determined at run time. However, dynamic allocations must be manually deallocated, or else your program will leak memory.

or a better design

A popular design pattern for dynamic allocation is RAII. The standard library already has a RAII container for character strings: std::string. So, to copy a string into a member of a struct, a good design is to have a string as the member:

struct test {
    std::string name;
};

test t1;
t1.name = str;
eerorika
  • 232,697
  • 12
  • 197
  • 326
0

There is no reason to use const char *, since its more error-prone and harder to implement you should use std::string instead.

std::string also allows you to get const char * to string using c_str() method.

But if you have to implement name as C-style string, here is what you have to do:

  • Allocate enough space on heap using new.
  • Cast to non-const
  • Copy strings using strcpy
  • Free memory in destructor

Constructor:

test(const std::string& str) : name(new char[str.length() + 1])
{
    strcpy((char*)name, str.c_str()); }
};

[Live demo]


Also as @Pixelchemist correctly noted, there are important rules of zero/three/five. If your class contains resources which arent copied/destructed correctly them self, like pure pointers aren't (if you would use smart pointers, it would be different story), you have to implement these as well:

  • copy constructor
  • copy assignment operator
  • destructor

  • move constuctor
  • move assignment operator

For extended informations read this excellent answer about rule of three.

kocica
  • 6,412
  • 2
  • 14
  • 35