×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Jobs

strcpy_s in constructor

strcpy_s in constructor

strcpy_s in constructor

(OP)
Windows 7, Visual Studio 2008, C++

The question is: why is the strcpy_s returning an error that the destination is too small?

I am following a book and playing around with constructors.  The constructor in question is this:

CODE

C_box( char * new_name, float w = 1.0, float l = 1.0, float h = 1.0 )
{
  if( new_name == NULL )
{
            name = NULL;
        }
        else
        {
            size_t name_size = strlen( new_name );
                   // this started with "name_size + 1" then bumped
                   // it up to 10.  That made no difference.
            name = new char[ name_size + 10 ];
            errno_t error_number = strcpy_s( name, name_size, new_name );
        }
        width = w;
        length = l;
        height = h;
    };

Two instances of the class are created:

CODE

    C_box box1;
    C_box box2( "two", 2.0, 2.0, 2.0 );

The first is okay (uses a different constructor), and the second fails at the strcpy_s.  So I when step into the strcpy_s function the code shown is from file tcsscpy_s.inl and looks like:

CODE

_FUNC_PROLOGUE
errno_t __cdecl _FUNC_NAME(_CHAR *_DEST, size_t _SIZE, const _CHAR *_SRC)
{
    _CHAR *p;
    size_t available;

    /* validation section */
    _VALIDATE_STRING(_DEST, _SIZE);
    _VALIDATE_POINTER_RESET_STRING(_SRC, _DEST, _SIZE);

    p = _DEST;
    available = _SIZE;
    while ((*p++ = *_SRC++) != 0 && --available > 0)
    {
    }
    if (available == 0)
    {
        _RESET_STRING(_DEST, _SIZE);
        _RETURN_BUFFER_TOO_SMALL(_DEST, _SIZE);
    }
    _FILL_STRING(_DEST, _SIZE, _SIZE - available + 1);
    _RETURN_NO_ERROR;
}
Reference lines
    _VALIDATE_STRING(_DEST, _SIZE);
    _VALIDATE_POINTER_RESET_STRING(_SRC, _DEST, _SIZE);

First I find it curious that the debugger does not provide any information about  _DEST, _SIZE, etc, so I cannot determine what it is doing.   
Regardless, the variable "available" gets the value 3, the size of the source string.  The while loop does the copy and available bumps down to 0.  That looks right to me.  Then the debugger hits:

CODE

if (available == 0)
There is something wrong here.
The if is taken and and Visual Studio pops up an error box containaing, in part:
Expression:(L"Buffer is too small" && 0 )
What else could happen?  Available starts at the size of the string being copied and counts down to zero.  Why should this result in an error?

We need to know what a dragon is
before we study its anatomy.
(Bryan Kelly, 2010)
 

RE: strcpy_s in constructor

Add 1 to name_size in strcpy_s call: remember trailing zero byte in C text strings.
 

RE: strcpy_s in constructor

A better idea would be to stop messing with char* pointers in your C++ programs and use a std::string in its place.

When you positively have no choice but to read it as a char array at some point, then use name.c_str()


 

--
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.

RE: strcpy_s in constructor

(OP)
ArkM,
I did not think of that.  Thank you.

Not to take away from your post, But that led to some other tests.  First, the help file for strcpy_s includes the line:

CODE

strcpy_s( string, "Hello world from " );
The help file appears to be wrong as the compiler says strcpy_s does not take 2 argugments.

Next the help file shows three more lines of code that contain strcat_s but not strcpy_s.  This despite the fact that the top of the help page does not include strcat().

They also show the use of _countof as in:

CODE

strcat_s( string, _countof(string), "strcat_s!" );

Maybe that returns the required value for strcpy().  However:

CODE

... char * new_name; ...
size_t name_size_b = _countof( new_name );
size_t name_size_b = _countof( *new_name );
Neither one of those two options will compile.  Both of them solicit error C2784.  I would paste the message in but the compiler has copy disabled for error messages.  I guess they have decided that their error messages are proprietary.

So, does anyone know how to use _countof?
And, i presume I should just add one to the length when doing a strcpy_s.  Is that correct?





 

We need to know what a dragon is
before we study its anatomy.
(Bryan Kelly, 2010)
 

RE: strcpy_s in constructor

(OP)
Salem,

You are undoubtably right.  
Problem is, I am not yet good at this and Horton's VS 2008 C++ uses char * all over the place. So I start with what he has.  I presume that "char *" is an easy way to get pointers and illustrate the need for copy constructors.

I must wonder: Why did Horton, in his relatively recent book, use char * so much rather than std:string?

But that's really rhetorical, unless he lurks these pages we will never know his reasoning.

We need to know what a dragon is
before we study its anatomy.
(Bryan Kelly, 2010)
 

RE: strcpy_s in constructor

Better get *_s functions out of your head! IMHO these non-standard freaks add nothing to your program security and robustness.

Apropos, non-standard _countof macros works correctly for statically allocated arrays only. It's a simple "sizeof(a)/sizeof*a"...
 

RE: strcpy_s in constructor

It seems to me you need a different book.

That a "C++" book published a whole decade after the C++ standard was released is STILL using char* for strings is frankly a rip-off.

> I must wonder: Why did Horton, in his relatively recent book, use char * so much rather than std:string?
No doubt it is the same old book tarted up for the latest compiler, without actually revising any of the material.

Personally, I would go with this book list.
http://rudbek.com/books.html

Accelerated C++ is well recommended, and it isn't some 1000+ page door stop.

I also suggest avoiding any book which mentions a particular vendor in the title.  Even if the material is good, you're inevitably going to learn some things which are compiler specific.  Whilst this is not a bad thing per se, you won't necessarily know it is compiler specific until you use another compiler.  But by then, it's too late.

Product neutral books are more likely to focus on the language (which should be good for all compilers), rather than being tied to any particular compiler.


 

--
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.

RE: strcpy_s in constructor

(OP)
Salem wrote:

Quote:


Accelerated C++ is well recommended, and it isn't some 1000+ page door stop.I also suggest avoiding any book which mentions a particular vendor in the title.  Even if the material is good, you're inevitably going to learn some things which are compiler specific.  Whilst this is not a bad thing per se, you won't necessarily know it is compiler specific until you use another compiler.  But by then, it's too late.

I am going with Accelerated C++.

On the vendor specific, Visual Studio C++ has an incredible number of utilities to display data within Windows and a myriad of ways to display that data.  It seems like an incredibly difficult task to jump from just C++ to C++ for user interfaces in Windows.  I have done a lot of coding, but not much C++ yet.  I feel like getting fluent with Visual Studio is just as, if not more, difficult than learning the concepts of C++.

We need to know what a dragon is
before we study its anatomy.
(Bryan Kelly, 2010)
 

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close