Problems with function returning character vector in C ++

1

Follow the code:

#include <iostream>

char* criaVetor(){

     char vetor[20]="Olá mundo!";
     return vetor;
}

int main(){

    char retorno[20]=criaVetor;

    std::cout << retorno;

    return 0;
}
  

error: array must be initialized with a brace-enclosed initializer

I do not quite understand, what do I have to do to get around this error?

    
asked by anonymous 14.08.2017 / 16:54

2 answers

0

Leonardo, it seems that you are mostly confusing things from one language to another. I'll explain to you the mistakes I found.

char retorno[20] = criaVetor ;

First, function call has parentheses, always, even without arguments.

char retorno[20] = criaVetor() ;

Second, to initialize a chars vector by quoting element values, you must use "Olá mundo!" or {'O','l','á',' ','m','u','n,'d','o','!','retorno'} . No function can return this.

In this case, the function returns a pointer to char, so it can only initialize a pointer to char, not twenty array elements. The std::string::copy is treated as a constant pointer, so it can not be assigned or initialized.

char *retorno = criaVetor() ;

If you eventually want an array of twenty elements to have the value of the cells in the returned pointer, you will have to copy those values one by one. For this, you can use the #include <string> function of the string library ( static ).

Third, in the function you return the pointer that points to cells that only exist during the execution of the function (locally allocated in the execution stack). At the end of the function, the cells in that pointer no longer exist, which is a risk of a bug.

char* criaVetor(){
     char vetor[20] = "Olá mundo!";
     return vetor;
}

It has three solutions and I think in the fastest case is to give an extended life to the cells of this function using keyword static . With the keyword new in a local variable, it will have the same lifetime as the program, ie it will exist even after the function is finished and the next call will have the same value as in the last time.

char* criaVetor(){
     static char vetor[20] = "Olá mundo!";
     return vetor ;
}

Another way is to allocate the array of 20 elements using keyword std::string::copy , then assign the values of the cells with the string (for this you can copy using the delete function quoted above) and return. But the problem is that you will have to control its existence, using %code% when you no longer need it.

There is one more option (I think it's more appropriate), which is the "no use of pointers to char" but rather of the string class (it's in the string library, which I mentioned shortly), which then controls all those questions involving pointers , allocations, etc. Pointers to char is more C language stuff than C ++, since class string is C ++ and exists exactly to make your life easier. Use pointers only if necessary.

Any questions?

    
15.08.2017 / 21:59
3

There are some problems in this code, what is being shown is that you are calling the function without the parentheses. If you call criaVetor() this error disappears.

But it actually has another error, you are creating a local vector ( stack a>) within this function and returning it, the problem is that the moment the function terminates that vector is destroyed then you are returning something that can not be accessed.

One possible solution is to allocate in the heap , where the content is not destroyed. Although this is not ideal, it is best to allocate memory where it will be used and pass a pointer from this allocation, which can usually be local even and then the function uses this storage location, so you better control the life time and run less risk of having memory leak. In C you usually use malloc() , in C ++ you usually use the new operator.

But there is another problem, is using C ++ and trying to use a vector of characters. This is not recommended, use a string and forget about all those difficulties. That is, in C ++ program in C ++, not in C. Something like this:

#include <iostream>
#include <string>
using namespace std;

string criaString() {
    return "Olá mundo!";
}

int main(){
    string retorno = criaString(); //esta variável nem é necessária
    std::cout << retorno;
}

See running on ideone . And no Coding Ground . Also I put GitHub for future reference .

    
14.08.2017 / 17:03