简体   繁体   中英

How could I use a reference of a pointer when re-allocating memory?

Unlike in the C, as what i've learned about C++, there is no instruction realloc in C++ for it is not recommended. But when I was creating a function that concatenates strings and at the same time can be dynamically re-allocating the given strings' memory without using vector , I've come to need some code just like as the realloc instruction functioning. So what i've come up with is that using a reference of a pointer(in the code char* &des ) could adjust the size of memory by using the usual instruction of C++, new and delete . However, an error occured: "[Error] invalid initialization of non-const reference of type 'char*&' from an rvalue of type 'char*'" Why is it impossible to initialize char*& type with the type char* ? Isn't it the same as a statement char* &des = str0 ? The total code is as follows:

void Mystrcat(char* &des, const char* src) {
    int des_len = Mystrlen(des); // Mystrlen just returns the length of a string with the type unsigned int excluding null character
    int src_len = Mystrlen(src);
    
    char* temp_str = des;
    des = new char[des_len + src_len + 1]; 
    
    //a copy process
    for(int i = 0; i < des_len; i++) {
        des[i] = *(temp_str + i);
    }
     
    for(int i = des_len + 1; i < des_len + src_len + 1; i++)
        des[i - 1] = *(src + i - des_len - 1);

}
int main() {
    char str0[100] = "Hello";
    Mystrcat(str0, ", World!"); 
    std::cout << str0 << std::endl; //expecting "Hello, World!" to be printed
    return 0;
}

What i've tried before is just writing the parameter char* des instead of char* &des . But unlike in main function, it was not possible to get the size of total str0 array in Mystrcat function by simply using sizeof . As a result, I thought it would be good to use pointer reference. I was expecting this a reference of a pointer parameter to be working properly because it is equal to the statement char* &des = str0 .

The problem here is:

char str0[100] = "Hello";

str in this case has a pinned (static) memory address. It's immutable in terms of its address -- so to speak -- because it's not a pointer to a string, but an array of characters of a size that can be evaluated at compile-time (not dynamically allocated). Making str itself point to a different address makes no sense and invites a whole lot of chaos. Even modifying the original pointer address to a dynamically-allocated array is chaos since you need the original address to properly free it. Think of an array of T as T* const (the address is immutable even if the contents are mutable and even if dynamically allocated, you need to keep the original address unmodified).

But in general as a non-profit advertisement of sorts, I want to encourage embracing value semantics as much as you can over pointer/reference ones. So instead of:

void Mystrcat(char* &des, const char* src)
{
    // Modify the address of 'des' in place.
}

You can do:

[[nodiscard]] char* Mystrcat(char* des, const char* src)
{
    // Input an address to a string and return an address to a new string.
}

Then you can pass an address to your array, get a pointer to a new modified copy (same thing you were doing before), and store the pointer to the new array (along with freeing it when you're done). There's little benefit to modifying things in place if you're just going to allocate a new string anyway.

This is still ignoring the conventional advice that you should use std::string which is what I think you need now and wholeheartedly echo over all this low-level pointer stuff and manual heap allocation and deallocation (which can be disastrous without the use of RAII when combined with thrown exceptions) But later you might want to deviate from it if the SBO is too large or too small or if the SBO optimization is counter-productive, for example but that's diving deep into things like custom memory allocators and whatnot and something you typically reserve until you encounter profiler hotspots and really know what you're doing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM