char array manipulation

Can anyone tell me what is wrong in this code and how to fix it? here bytearray gets destroyed as it reached end of the loop, i guess.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

#include <bytearray> //it provides an array of bytes. It can be used to store both raw bytes (including '\0's) and traditional 8-bit '\0'-terminated strings. It can embed '\0' bytes. Using bytearray is much more convenient than using const char *.

const char* getstring()

{

bytearray btar("Sample output"); // creates byte array of data

return btar.constdata();

}

int main(int argc, char *argv[])

{

const char *str = getstring();

cout << str << endl;

return 0;
Last edited on
I have never used "bytearray" but I think you're right. btar.constdata() probably returns a pointer to the internal array which is then destroyed when btar goes out of scope which means there is nothing useful you can do with the returned value from getstring().

Why not return a std::string from getstring() instead?
Last edited on
bytearray is not a standard class, I think?

But, in your getstring() function you create a local instance of bytearray with "automatic" storage duration (allocated on the stack). You then return a pointer to what appears to be an internal buffer of the local bytearray object. But that object obviously is going to be destroyed as soon as the getstring() function returns... So, I think the problem is that you are effectively returning a "dangling" (invalidated) pointer!

Try this:
1
2
3
4
5
const char* getstring()
{
    bytearray btar("Sample output"); // creates byte array of data
    return strdup(btar.constdata()); // <-- copy string to heap-allocated memory
}


But then the caller of getstring() must free() the heap-allocated memory when no longer needed!

________

Of course, using a bytearray object is rather pointless in your example. Could be simplified to:

1
2
3
4
5
const char* getstring()
{
    static const char *const MY_STRING = "Sample output"; // <-- const string in static memory
    return MY_STRING;
}

Last edited on
kigar64551, isn't strdup a new feature in C23 that is not present in standard C++ yet?

If you do something like this you need to make sure to deallocate the memory when you are finished using it (I think with strdup you should use free rather than delete) otherwise you'll have a memory leak.

That's why I recommended std::string in my previous post. Using std::string is easier because you don't have to worry about the memory allocations and deallocations. It's all taken care of internally by the std::string class.
Last edited on
Sure, but if you use std::string then using bytearray is pointless to begin with.

If you really have to use a bytearray, for whatever reason, and you want to "safely" return a char* string from that object's internal buffer, then you have to make a copy of the string, in one way or another...

strdup() conforms to SVR4 (Unix SystemV 4.0), released ~1988, as well as POSIX.1-2001. Therefore it is certainly available in all Linux and Unix/BSD systems. Also, MSVC provides that function on Windows.
Last edited on
kigar64551 wrote:
Of course, using a bytearray object is rather pointless in your example. Could be simplified to: ...

Your original code was fine:
1
2
3
4
const char* getstring()
{
    return "Sample output"; 
}

There is no need to declare a local static const char*. You're returning a copy of the pointer anyway so there is no need to make sure the pointer stays alive after the function has ended. What matters is that the char array stays alive and that is not a problem here since string literals give you char arrays that have static storage duration and will therefore stay alive for the rest of the program.
kigar64551 wrote:
Sure, but if you use std::string then using bytearray is pointless to begin with.

I agree, but maybe this is a just dumbed-down example and in the real program they have a bytearray, for some reason, that need to be converted to a string.
There is no need to declare a local static const char*.

I know, its effectively the same. Just wanted to make the fact that a "plain" C-string is not an object that will be destroyed when the function returns a bit more explicit :-)
Last edited on
It's like doing:

1
2
3
4
5
int getint()
{
    static const int MY_INT = 5;
    return MY_INT; 
}
Last edited on
I need to return a char * pointing to "Sample output". Can I do this way?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

const char* getstring()
{
    return "Sample output";
}

int main()

{

    const char *str = getstring();

    cout << str << endl;

    delete str;
    return 0;

}
Yes, except you should not use delete in this case.

Only use delete on things that you've created with new.

Only use free on things that you've created with malloc, calloc and similar C functions.
Last edited on
Thanks all for your valuable inputs here. Closing this thread now.
Topic archived. No new replies allowed.