0

I want to use pointer to store a char array generated by a function, then pass it to another function as a parameter, the code looks like this:

char* randString(){
    //generate a rand string formed by 6 letters and numbers
    char rSet[36];//a char set contains 0-9 and A-Z
    for (int i=0;i<10;i++) rSet[i]=i+48;// get ASCII of 0-9
    for (int i=10;i<36;i++) rSet[i]=i+55;// get ASCII of A-Z

    char rString[7];
    for (int i=0;i<6;i++){
        int ind=rand()%36;
        rString[i]=rSet[ind];// generate the random string
    }
    rString[6]='\0';
    return rString;
 }
void Print(char *b){
    cout<<b;
}
int main(int argc, char* argv[])
{
    char* a=randString();
    Print(a);
}

the randString() function return a string composed by 6 random letter and number, then I store it with *a . when I tracked the pointer with debug, i found the content of *a is correct, with some stuff like "VG5GH2". However, when it was passed to Print() function, the content of the pointer was lost. Even the memory address is still the same, the value in there become some completely random stuff. If I do Print(randString()) also the same thing happend. Could someone help me out about this issue? I am pretty new to C++ and still not very clear with the use of pointer. Many thanks

Alex
  • 50
  • 5
  • 1
    [Dangling pointers](http://stackoverflow.com/a/17997314/1171191). `rSet` is local to the function `randString`. It goes away after the function returns. You can't keep a pointer to it. – BoBTFish Aug 04 '14 at 09:28
  • 4
    See: http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope and http://stackoverflow.com/questions/4824342/returning-a-local-variable-from-function-in-c – Ani Aug 04 '14 at 09:28
  • 1
    Also, [`std::string`](http://en.cppreference.com/w/cpp/string/basic_string). – BoBTFish Aug 04 '14 at 09:34
  • @Ani when I change the content of randString() into something like {return "Hello"}, it will work without problem. what is the different between those two? thank :-) – Alex Aug 04 '14 at 09:41
  • @Alex Your "Hello" example is returning a `char const *` to a read-only literal string stashed somewhere in a read-only segment. It would *likely* fail if you changed that to `char str[] = "Hello"; return str;`. – WhozCraig Aug 04 '14 at 09:43
  • 2
    And fyi, one way to do this with modern C++ [can be seen here](http://ideone.com/Fq7J5B). `` rocks. – WhozCraig Aug 04 '14 at 09:45
  • @WhozCraig wow just tried that, u are absolutely right! thanks! – Alex Aug 04 '14 at 09:52

3 Answers3

2

When you create the character array it is being created in local scope and can't be used outside that function in which you're creating it. To tackle this problem the best way you can do in the same code is by creating the character array on heap. This will give you the exact result that you want to get.

char *rString;
rString = new char[6];

Finally, one should delete the variables created on heap! and you can do it by deleting the char pointer in which you're receiving the string from function

char* randString();

As

delete []a; 

at the end of your program.

Ali Mohyudin
  • 242
  • 2
  • 10
1

Memory issue buddy you just send back first char of your random string, the others destroyed when function done its job.But if you create them with 'new' keyword you has no problem to do anything you want.I hope this will help.

char* randString(){
    //generate a rand string formed by 6 letters and numbers
    char rSet[36];//a char set contains 0-9 and A-Z
    for (int i=0;i<10;i++) rSet[i]=i+48;// get ASCII of 0-9
    for (int i=10;i<36;i++) rSet[i]=i+55;// get ASCII of A-Z
    srand(time(nullptr));

    char *rString=new char[7];
    for (int i=0;i<6;i++){
        int ind=rand()%36;
        rString[i]=rSet[ind];// generate the random string
    }
    rString[6]='\0';
    return rString;
}
void Print(char *b){
     cout<<b;
}

int main()
{
     char *a=randString();
     Print(a);
     delete[] a;
     return 0;
}
Scis
  • 2,934
  • 3
  • 23
  • 37
oknsnl
  • 351
  • 1
  • 11
0

You are returning a pointer to a local variable inside the function. You are referencing stack memory- which will get used by other functions, variables as soon as the method/function exits.

One of the answers here mentions "dangling pointers". That term is applicable only when you malloc() then free() and re-used the pointer;

int *i = (int *) malloc(sizeof(int));
*i = 12;
free(i); // oops
printf("i = %d\n", *i);

If you want to write functions that return strings (char*), you have two options:

  1. Allocate the memory inside the functions and then return it
  2. As one of the parameters, you need to get the output buffer, and output buffer size.
  3. As you are coding in C++ - use std::string everywhere, and don't use char* at all (note to self - still on output there is a memory copy... maybe passing the std::string out parameter as reference will help...?)

Example 1, note how we call the function and then release memory. Memory management is done by the function. This is not optimal, and I do not recommend this.

// in this function, the caller must release the memory
char* randStr1(int len) {
   char* c = (char*) malloc(len), *cc = c;
   for (int i=0; i<len; i++) {
         *cc = rand()l
         *cc++;
   }
   return c;
}

void foo1() {
   char *c = randStr1(10);
   printf("%s", c);
   free(c);
}

Example 2: in this example, the memory allocation is done by the caller

char* randStr2(char *buffer, uint len) {
    char *c = buffer;
    while (len!=0) {
        *c = rand();
        c++;
        len --;
    }
    return buffer;
}

void bar1() {
   char buffer[100], *p;
   p = randStr2(buffer, 100);
   printf("%s", buffer); // or printf("%s", p);
}

Note how in the last example we do not need to de-allocate memory from the heap. The compiler will allocate and de-allocate memory from the stack.

elcuco
  • 8,948
  • 9
  • 47
  • 69
  • It's a **c++** question and not a **c** question, there's no good reason to use `malloc` and `free`here... – Scis Aug 04 '14 at 10:08