0

I'm working with a piece of C++ code that reads lines from a txt file and then assign each line to to an array called lines. Then it calls a function that converts each element in the lines array to a char array and then return the resulted char array. This step is where I stuck. How could I return a char array from the function toChar and assign the returned array to another array so I can use it as I need? (the rest of the code should use each returned char array to write it in a pipe, this not important right now but just to clarify why I need to learn to return an array from a function)

Here is the code I'm using:

#include <fstream>
#include <iostream>
#include <string.h>
#include <unistd.h>
#include <cstdlib>


using namespace std;

char * toChar(string line);

int main()
{
string lines[0] = "line1";
char* a = toChar(lines[0]);



return 0;
}

char * toChar(string line)
{
    char a[1024];
    strcpy(a, line.c_str());
    return a;
}

Please note that in this code I'm trying to shrink the code so I'm assigning a simple string value to the array

when I try to compile this code, the error below appears:

warning: address of local variable 'a' returned

any help or suggestion is greatly appreciated..

Husain Alhamali
  • 823
  • 4
  • 17
  • 32
  • 1
    Possible duplicate of [c++ warning: address of local variable](http://stackoverflow.com/questions/2862494/c-warning-address-of-local-variable) – Paolo M Dec 10 '15 at 10:17
  • 1
    Why not using [`std::string`](http://www.cplusplus.com/reference/string/string/) instead of C array ? – Richard Dally Dec 10 '15 at 10:17
  • 2
    I'm surprised that `string lines[0] = "line1";` doesn't give an error, because it's also wrong. It could be `string lines[1] = {"line1"};` – interjay Dec 10 '15 at 10:21

3 Answers3

3

First use a const & in passing the string to the function to avoid the unnecessary copying, and be able to use temporaries, e.g. toChar("I am temp");

The are the following alternatives:

(1) Return std::string

 std::string toChar(std::string const & line)
 {
     char a[1024];
     strcpy(a, line.c_str());
     return a;
 }

Of course it is assumed that line is smaller than 1024 chars with the null termination symbol

(2) Return an allocated array the

char * toChar(std::string const & line)
{
  char * a = new char[1024];
  strcpy(a, line.c_str());
  return a;
}

but you will have to actually manage it and delete it later.

(3) Allocate the array and pass it to the function

void toChar(string const & line, char a[])
{
 strcpy(a, line.c_str());
}

I imagine that you actually want to extract a C-string from an std::string , or some part of it. The proper way to do it is (3).

g24l
  • 3,055
  • 15
  • 28
  • Anyway, thanks a lot for your answer too, I'm sure it will help me somehow in other places, or at least anyone may find your solution useful. Thanks again – Husain Alhamali Dec 10 '15 at 10:59
  • @g24l I would not use you alternatives because they could cause an overflow. I would edit the number (1) to check against the size of the string and the number (2) to allocate depending on the size. And I find version (3) is very dangerous. – dkg Dec 10 '15 at 11:46
  • @dkg , they are, memory management and space are left to the user of the function . ( 1 ) is dangerous indeed, but it is what the op gave as an example in his code, I assume he knows better . Keep in mind that SO is not for code-review but for answering questions. – g24l Dec 10 '15 at 11:57
1

The warning is correct and practically is an error. You're declaring the char array locally so it will be deleted after going out of scope of that function and its address will be no more valid.

Since you're using c++ avoid char array and use a std::string.

Jepessen
  • 11,744
  • 14
  • 82
  • 149
1

If you want to access to the internal storage of your string you can call line.c_str() which returns a const char *.

Hence you won't need you function toChar that creates a local array that will go out of scope at the end of your function.

You could simply do :

int main()
{
    string lines[0] = "line1";
    const char* a = lines[0].c_str();


    return 0;
}

But I advise you to keep manipulating std::string as they will handle string better than a simple char *. And if you want a copy, just do it : std::string mycopy = lines[0].

dkg
  • 1,775
  • 14
  • 34
  • Nice!, Thanks too much, @dkg – Husain Alhamali Dec 10 '15 at 10:33
  • @AliAlhamaly , but this was your question : "How could I return a char array from the function toChar and assign the returned array to another array" , and finally you are not using toChar at all ~?~! – g24l Dec 10 '15 at 10:49
  • you are right, I've posted this question but actually my goal of my question wasn't how to return an array from a function, I just thought it is the best way to get a `char array` from a `string` is to do so in a function, now @dkg posted a better manner to achieve that with no need to a separated function so why I should stick on my current way?! Please refer to my question above and you will notice that I've provided a brief of why I will need the array, it doesn't matter whether I achieve that using a function or even using the piece of code above @g24l – Husain Alhamali Dec 10 '15 at 10:53
  • @AliAlhamaly no problem there, but you should accept an answer that answers the question, you can upvote those that have been helpful. – g24l Dec 10 '15 at 10:57
  • Yeah sorry for that, I've accepted your answer, regards – Husain Alhamali Dec 10 '15 at 11:00