0

In C++ when you're passing an array of char when instantiating a class, is it possible to put a cap on the bytes that are copied as to prevent an overflow if you're uncertain of the number of characters coming in?

My implementation is not based on user input so I know it's going to be fine, but I'm wondering for general knowledge.

e.g. (from this post)

class test2 {
    char name[40];
public:
    test2() : name("Standard") {};
    void display() { cout << name << endl; }
};

e.g. (edited version of this post)

class test2 {
    char name[40];
public:
    test2(const char *charsComingIn) : name(charsComingIn) {};
    void display() { cout << name << endl; }
};

As a sidenote, I haven't tested the second example but that's the gist of what I'm trying to do at the moment. Any corrections are welcome to concept of implementation.

Community
  • 1
  • 1
J-a-n-u-s
  • 1,469
  • 17
  • 20
  • 3
    you can't initialize a `char[40]` from a `const char*`, so... problem averted! – Mooing Duck May 06 '16 at 23:41
  • 2
    There is `strncpy`. Typically this is regarded as inferior to managed solutions like `std::string`. – Waleed Khan May 06 '16 at 23:43
  • You aren't passing an array of chars. – user253751 May 06 '16 at 23:51
  • Problem averted but solution remains missing. So is there a way to have the data copied over using that inline initialization or should I just do it the normal way in the function? I was just looking for a shorthand version if it exists. – J-a-n-u-s May 07 '16 at 00:13
  • 1
    @WaleedKhan `strncpy` is dagngenours. In case of overflow it not terminate string with `'\0'` – fghj May 07 '16 at 00:32
  • There is such variant http://stackoverflow.com/questions/11837078/initialize-a-constant-sized-array-in-an-initializer-list but much simpler if you call `strXcpy` inside body of constructor. – fghj May 07 '16 at 00:50

1 Answers1

1

You could use strncpy and potentially truncate:

test2(const char *charsComingIn) {
    strncpy(name, charsComingIn, sizeof(name));
    name[sizeof(name)-1] = '\0';
} 

This will definitely not overflow. However, the user wouldn't know if you truncated. If the latter is a concern, you might want to throw an exception.

Or you could only allow arrays that are small enough:

template <size_t N, class = std::enable_if_t<(N <= 40)>>
test2(const char (&in)[N]) {
    memcpy(name, in, N);
} 

Which wouldn't allow arbitrary c-strings.

Barry
  • 286,269
  • 29
  • 621
  • 977