Buffer of char* in c++ using strlen bug

88 Views Asked by At

i am trying to implement and + operator that gets rhs obj and lhs obj, the object contains char* string; for for e.g s1 contains "eden" s2 contains "sh" I want that s3 = s1 +s2 will be "eden sh" yet I cannot figure it out. I don't USE vector or std::string because the assignment was to do char* arr code:

auto *buff = new char[std::strlen(lhs.getName()) + std::strlen(rhs.getName()) + 2];
assert(buff);
std::strncpy(buff, lhs.getName(), std::strlen(lhs.getName()));
std::strncpy(buff + std::strlen(lhs.getName())," ", sizeof(char));
std::strncpy(buff + std::strlen(lhs.getName()), rhs.getName(), std::strlen(rhs.getName()));
tmp.setName(buff);

***set name is a function that copies buffer to m_name private data member.

the result is edensh

2

There are 2 best solutions below

1
Vlad from Moscow On

If you compare these two records

std::strncpy(buff + std::strlen(lhs.getName())," ", sizeof(char));
std::strncpy(buff + std::strlen(lhs.getName()), rhs.getName(), std::strlen(rhs.getName()));

you will see that they both start write at position buff + std::strlen(lhs.getName()). So the second call of strncpy overwrites symbols of the previous call of strncpy.

Also there is another problem. The result array does not contain a string because the stored sequence of characters is not appended with the terminating zero character '\0'.

Instead you could write for example

size_t n = std::strlen( lhs.getName() );

auto *buff = new char[n + std::strlen(rhs.getName()) + 2];
assert(buff);
std::strcpy( buff, lhs.getName() );
std::strcpy( buff + n, " " );
std::strcpy (buff + n + 1, rhs.getName() );
tmp.setName(buff);

Also instead of this call of the function strcpy

std::strcpy( buff + n, " " );

it is enough to write

buff[n] = ' ';

So you can also write

size_t n = std::strlen( lhs.getName() );

auto *buff = new char[n + std::strlen(rhs.getName()) + 2];
assert(buff);
std::strncpy( buff, lhs.getName(), n );
buff[n] = ' ';
std::strcpy (buff + n + 1, rhs.getName() );
tmp.setName(buff);
0
dinis On

It looks as if you are forgetting to account for the " " char on the offset.

std::strncpy(buff + std::strlen(lhs.getName()) + 1, rhs.getName(), std::strlen(rhs.getName()));