Can not pass pointer as a parameter to another function - c++

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

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.

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;
}

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:
Allocate the memory inside the functions and then return it
As one of the parameters, you need to get the output buffer, and output buffer size.
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.

Related

Convert char[][] to char**

I have a char[][]
char c[2][2]={
{'a','b'},
{'c','d'}
};
How can I convert it to char**?
The objective here is to use the converted char** as an input for a main function, which only accepts char** as its input. Both C/C++ solutions are acceptable.
While you could easily switch from char[] to char*, the same is not possible with char[][] and char**:
your char[2][2] is a 2 dimensional array having all the elements stored contiguously. To access one element, the compiler computes the offset knowing the size of each row.
char** points to an array that contains pointers to char. To access one element, your compiler computes the offset of the pointer in the left-most, load that poitner, then access to the element.
Workaround:
char *pc[2]={c[0],c[1]};
cout << pc[1][1]<<endl; // prints out the same as c[1][1]
// you can pass `pc` when a `char**` is needed
Remark: this compiles perfectly. However, some functions with an argument like char **av expect in reality av[i] to be a null terminated c-string. In this case, although your code would compile, the results might not be what you expect (buffer overflow).
You cannot convert a char[2][2] to char**, you can only convert it to char(*)[2],
char (*p)[2] = c;
The above is a pointer to array-of-2-char. Note that you need this 2 and cannot just write char** p, since in the latter case you are not able to perform pointer arithmetic (the pointer won't know how many elements to "jump" when incrementing, and you won't be able to address the elements of your array (in this case the rows)).
You could pass the array into the function like this:
char c[2][2] = {
{'a','b'},
{'c','d'}
};
char* x[] { c[0], c[1] };
func(x); // Assuming something like: void func(char** p);
NOTE: Although this answer may explain/illustrate the problem quite well other answers are preferable that recommend creating an automatic variable char*[2]; rather than allocating with new as this answer does.
Original answer:
The problem is char c[2][2] is a contiguous block of char. The compiler allocates only 4 char objects.
When you build an array of arrays (char** c) you need to manually allocate an array of pointers to char and then allocate (or assign) and array of char to each of those pointers.
So to convert your array char c[2][2] to an array of arrays you have to first create the array of pointers and then assign the array of the first element of each array of char to that.
Something like this:
void func(char** c)
{
for(int x = 0; x < 2; ++x)
for(int y = 0; y < 2; ++y)
std::cout << c[x][y] << ' ';
std::cout << '\n';
}
int main(int, char* argv[])
{
// one contiguous block of 4 chars
char c[2][2]={
{'a','b'},
{'c','d'}
};
char** param = new char*[2]; // create your own pointer array
param[0] = &c[0][0]; // assign the first element of each char array
param[1] = &c[1][0];
func(param); // call your func
delete[] param; // cleanup
}
If you have C++11 you can use a smart pointer to prevent memory leaks if an exception is thrown or someone forgets to delete.
int main(int, char* argv[])
{
// one contiguous block of 4 chars
char c[2][2]={
{'a','b'},
{'c','d'}
};
// use a smart pointer
std::unique_ptr<char*[]> param(new char*[2]);
param[0] = &c[0][0];
param[1] = &c[1][0];
func(param.get()); // now if this throws, no memory leak
// delete[] param; // NO NEED TO DELETE
}

How to make char array and std::string "in a relationship"?

I'm looking for a way to associate a char array with a string so that whenever the char array changes, the string also changes. I tried to put both char array and string variables in a union but that didn't worked as the compiler complained...
Any ideas are welcome...
class Observable_CharArray
{
char* arr;
std::function<void(char*)> change_callback;
public:
Observable_CharArray(int size, std::function<void(char*)> callback)
: arr(new char[size]), change_callback(callback){}
~Observable_CharArray()/*as mentioned by Hulk*/
{
delete[] arr;
}
void SetCallback(std::function<void(char*)> callback)
{
change_callback = callback;
}
/*other member function to give access to array*/
void change_function()
{
//change the array here
change_callback(arr);
}
};
class Observer_String
{
std::string rep;
void callback(char* cc)
{
rep = std::string(cc);
}
public:
Observer_String(Observable_CharArray* och)
{
och->SetCallback(std::bind(&callback, this, _1));
}
/*other member functions to access rep*/
};
The design can definitely be improved.
There can be other ways to solve your actual problem rather than observing char arrays.
The problem is that the std::string may change the string array inside (especially when it resizes). For instance, c_str returns the address of the current string - documentation says that "The pointer returned may be invalidated by further calls to other member functions that modify the object.".
If you're sure you won't call string methods (hence the string will stay at the same memory location), you could try accessing the c_str pointer (your char array) directly and modify its content.
std::string str = "test";
char* arr = (char*)str.c_str();
arr[3] = 'a';
NOTE: I strongly advice against this unless in a testing context.
In other words, the string class doesn't guarantee it's going to stay in the same place in memory - meaning trying to access it through a char array is impossible.
The best is to create another string class that enforces the char array to always stay the same size (and so can stay in the same memory position all the time). You could also create a bigger array (max size string for instance) to cope with any string size changes - but that should be enforced in your wrapper class.
Well you can do this, but you shouldn't
#include <iostream>
#include <string>
int main()
{
std::string test("123456789");
std::cout << test << "\n";
char* data = &test.front(); // use &(*test.begin()) for pre-C++11 code
for ( size_t i(0); i < test.size(); ++i )
{
data[i] = 57 - i;
}
std::cout << test << "\n";
}
Output will be
123456789
987654321
This however goes again everything std::string is trying to facilitate for you. If you use data, you risk causing UB and changes to test may make data point to garbage.
You should not do this!
However, there are many (dangerous) ways to achieve it:
char* cStr = const_cast<char*>(cppStr.c_str());
or
char* cStr = const_cast<char*>(cppStr.data());
or
char* cStr = &cppStr[0];
But beware that the cppStr might be reallocated whenever you touch it, hence invalidating your cStr. That would crash at some point in time, although maybe not immediately (which is even worse).
Therefore, if you are going to do this anyway. Make sure to cppStr.reserve(SOMETHING) *before* you get the cStr out of it. This way, you will at least stabilise the pointer for a while.

Returning char* from function not working

Visual studio c++ shows that "string" on line 24 has one array element, but the top contains all the text that was input by the user. But when I send to PutString(), it disappears. Why?
#include <stdio.h>
void PutString( const char* pChar ){
for( ; *pChar != 0; pChar++ )
{
putchar( *pChar );
}
}
char* GetString(){
char c[100];
int i = 0;
do
{
c[i] = getchar();
}while( c[i++] != '\n' );
c[i] = '\0';
// PutString( c );
return c;
}
void main(){
char* string = GetString();
PutString( string );
}
Because c is a local variable within GetString and you are returning its address, after which it disappears (moves out of scope). That's undefined behaviour - you're not allowed to use stuff that's gone out of scope. In fact, if you run that through gcc, it tells you that quite explicitly:
qq.cpp:9: warning: address of local variable ā€˜cā€™ returned
If you want to return non-simple things (such as arrays instead of integers or floats, which make a copy for you) from a function, you need to (for example) dynamically allocate it so that it survives function return. Something like changing:
char c[100];
into:
char *c = malloc (100); // or equivalent 'new'.
(and remembering to free/delete it eventually, of course).
Even though you may see it in the debugger when you return from GetString, it's still not guaranteed as per the standards.
In any case, there's a good chance the next stack manipulation (such as calling PutString) will wipe out the information.
Here's a C++ version that does it the new/delete way:
#include <stdio.h>
void PutString (const char* pChar ){
for (; *pChar != 0; pChar++)
putchar( *pChar );
}
char* GetString (void) {
char *c = new char[100]; // memory behind c will survive ...
int i = 0;
do {
c[i] = getchar();
} while (c[i++] != '\n');
c[i] = '\0';
return c;
} // ... past here ...
int main (void) {
char* string = GetString();
PutString (string);
delete[] string; // ... until here.
return 0;
}
I should also mention that there are probably better way to get line-based input in both C (fgets or see an earlier answer of mine) and C++ (such as the string getline and the char array getline).
You are returning pointer to a variable that is local to the function in GetString(), when the function returns, the space allocated to the variable is reclaimed.
To fix these you can either dynamically allocate space for the character array or declare it as static so that the lifetime of the variable becomes the entire program.
You GetString will not work correctly as the string (char c[100]) is put onto the stack. When the function gets to the return this will be deleted.
Either use malloc or pass into the function the array.

Return string array from function in C++

I am having problem handling string array in C++.I tried below two methods.Still
not able to resolve the problem...Here it goes :
When I use :
string* fun(string* a,string*b)
{
string c[];
return c; /* c is string array type*/
}
it returns first string stored in string array c.I want whole string array to be returned.
When I used:
vector<string> fun(vector<string> a,vector<string> b){
vector<string> c;
return c;
}
still,i got some errors.
can you help me know where is the problem in both cases.
What modifications are required to obtain the desired result..
How can I handle string array in C++.
Thanx in advance !!
In the first version, you are returning a pointer to a local variable (your array), which will not exists any longer when you leave the scope. You need to create your array on the heap, e.g. with malloc or new. If you allocate it manually, don't forget to deallocate it.
In the second version, you are returning a copy of the vector declared in your function (if you modify the strings in the returned vector, they'll not be modified in a et b). You are creating an empty vector and not adding anything in it, so it'll not contains any string, though.
If you've got to return an object more complex than string you should pass to your function a link to vector (in your code) and fill it with values. That's a fast and right method.
vector<string> fun(vector<string> a,vector<string> b, vector<string>& result){
res.push_back("one");
res.push_back("two");
res.push_back("three");
}
In C/C++ while returning a string from function a local buffer if returned will not work.
The returned pointer should be a static buffer(like static string c[]) or pointer to a buffer passed in by the caller function (like string *fun(string *a, string *b, string *c) ) or pointer to a memory obtained using malloc/new but not local array.
In your first snippet, you could try initializing with new to allocate the space yourself.
string* func() {
string* c = new string[3];
c[0] = "Hello";
c[1] = "World";
c[2] = "<3";
return c;
}
in main:
m = func();
for(int i = 0; i < 3; i++)
{
cout << m[i] << endl;
}
That should prevent it from losing scope once the function ends. Don't forget to deallocate the space. Note you are returning a pointer to an array, not an array. Also, I had no problem running your second snippet of code. Please always share the errors you are getting.
You can't return arrays directly in C++(it inherits this from C). The way around it is to stuff it into a struct.
struct returned_array
{
string result[100];
};
returned_array fun()
{
returned_array result;
result.result[0] = "whatever";
return result;
}
I just picked an arbitrary size 100 for the example. If you want to base the return size on the size of an array that gets passed in, you can add a template parameter:
template<int N>
struct returned_array
{
string result[N];
};
template<int N>
returned_array<N> fun(string (&)[N])
{
returned_array<N> result;
result.result[0] = "whatever";
return result;
}

Accessing variables from a struct

How can we access variables of a structure? I have a struct:
typedef struct {
unsigned short a;
unsigned shout b;
} Display;
and in my other class I have a method:
int NewMethod(Display **display)
{
Display *disp=new Display();
*display = disp;
disp->a=11;
}
What does **display mean? To access variables of struct I have used ->, are there other methods too?
As Taylor said, the double asterisk is "pointer to pointer", you can have as many levels of pointers as you need.
As I'm sure you know, the arrow operator (a->b) is a shortcut for the asterisk that dereferences a pointer, and the dot that accesses a field, i.e.
a->b = (*a).b;
The parentheses are necessary since the dot binds tighter. There is no such operator for double asterisks, you have to first de-reference to get to the required level, before accessing the fields:
Display **dpl = ...;
(*dpl)->a = 42;
or
(**dpl).a = 42;
Think of it as *(*display). When you want to pass the address of an integer to a function so that you can set the integer, you use:
void setTo7 (int *x) {
*x = 7;
}
: : :
int a = 4;
setTo7 (&a);
// a is now 7.
It's no different from what you have except that you want to set the value of a pointer so you need to pass the pointer to that pointer. Simple, no?
Try this out:
#include <stdio.h>
#include <string.h>
static void setTo7 (int *x) { *x = 7; }
void appendToStr (char **str, char *app) {
// Allocate enough space for bigger string and NUL.
char *newstr = malloc (strlen(*str) + strlen (app) + 1);
// Only copy/append if malloc worked.
if (newstr != 0) {
strcpy (newstr, *str);
strcat (newstr, app);
}
// Free old string.
free (*str);
// Set string to new string with the magic of double pointers.
*str = newstr;
}
int main (void) {
int i = 2;
char *s = malloc(6); strcpy (s, "Hello");
setTo7 (&i); appendToStr (&s, ", world");
printf ("%d [%s]\n",i,s);
return 0;
}
The output is:
7 [Hello, world]
This will safely append one string value to another, allocating enough space. Double pointers are often used in intelligent memory allocation functions, less so in C++ since you have a native string type, but it's still useful for other pointers.
**display is just a double pointer (a pointer to a pointer of type Display).
The ** means that its a pointer-to-a-pointer. Basically it points to another pointer that then points to something else, in your case a Display structure.
If you called the function with only the object you can access the members with the . operator.
int NewMethod(Display display)
{
Display disp = display;
disp.a=11;
}
But this way you are not modifying directly the Display display object but a local copy. Your code suggests that the changes to the object are needed outside of the function so your only option is the one you described (well, maybe passing the argument by refference but the syntax then would more or less the same (->)).
Since disp is a Pointer you have to use ->
If you just have a "normal" variable (i.e. on the stack)
Display d;
you can write d.a
A struct is the same as a class. The only difference (I am aware of) is that all members are public by default.
You can do (*disp).a=11;
it is called dereferencing