Pointer errors in the method of transmission(c++) - c++

I encountered a problem.I try to change the pointer,but pointer does not change.
Here is my code:
void TestPoint(char* point)
{
point=new char[10];
}
int main(int argc, char* argv[])
{
char* test=NULL;
TestPoint(test);
**//At this point the "test" is still null,why ?**
return 0;
}
Sorry ,My english is very poor,and I don't know how to insert the c++ code.

Imagine you're going to the airport
You pick up a piece of paper and write down which terminal you need to go to, which flight and seat.
You call for a taxi to the airport. The taxi company asks you "Which terminal". You consult your piece of paper and tell them "Terminal 3". On the journey, you tell your driver you are flying to Paris and he tells you "Oh, you really want to go to Terminal 1, it'll be much faster".
You let him take you to Terminal 1. You make your flight, have a week in Paris and fly home. As you are unpacking, you find the original piece of paper.
Does it say Terminal 1 or Terminal 3?
This is an example of "pass by value" and in C and C++ pointers are actually variables much like any other. "Terminal 3" is a pointer, it is an address of a place at an airport. '0x073aff10' is a 32-bit integer value, but it could also be the address of the location in memory in which my credit card number is stored. If I tell you "Terminal 3" I am passing the address of the terminal I need by value.
This line of code:
void TestPoint(char* point)
Declares a function called "TestPoint". Whenever this function is invoked, the computer will reserve new storage for a "char*" pointer and you will be able to refer to that storage in code with the variable name "point". The storage will be on the stack, when you leave the function, the stack "unwinds" upwards, the variable is gone.
This line of code:
TestPoint(test);
Invokes the function test point, passing it the value of variable 'test'. What you see in TestPoint is not the same as 'test' its a copy of the value of test at the time you entered TestPoint.
Pointers are basically variables, like any other, with a slightly special contract that lets you do some extra magic with them - you and the computer agree that they are going to contain memory locations of things.
What you need is the address of the pointer itself:
TestPoint(&test)
and TestPoint needs to take a pointer-to-a-pointer-to-char
void TestPoint(char** point)
and in TestPoint you need to dereference "point" once to get to the pointer-to-char
*point = new char[10]
Alternatively, you could just make TestPoint take no argument and return a pointer value.
char* TestPoint()
{
char point = new char[10];
return point;
}

Try this, passing the address of the pointer,
void TestPoint(char** point)
{
*point=new char[10]; //assign to location at point
}
int main(int argc, char* argv[])
{
char* test=NULL;
TestPoint(&test);
printf("test: %x\n",test);
return 0;
}
A more C++ idiom would be to pass by reference,
void TestPoint(char* &point)
{
point=new char[10]; //assign to point reference
}
int main(int argc, char* argv[])
{
char* test=NULL;
TestPoint(test);
printf("test: %x\n",test);
return 0;
}

void TestPoint(char** point)
{
*point = new char[10];
}
int main(int argc, char* argv[])
{
char* test = NULL;
TestPoint(&test);
/******/
return 0;
}

That's because function TestPoint receives a copy of the test variable, modifies it (assigning pointer to allocated memory) and then discards. If you imagine replacing char* with, for instance, int, things may get clearer.
The very minimal change you can do is rewrite TestPoint signature in the following way
void TestPoint(char*& point)
thus passing test variable via reference. These online lessons may be of help. Chapters 7.2 - 7.4 are about passing arguments to function.

Related

Pointer to Pointer Memory-address [duplicate]

Under what circumstances might you want to use multiple indirection (that is, a chain of pointers as in Foo **) in C++?
Most common usage as #aku pointed out is to allow a change to a pointer parameter to be visible after the function returns.
#include <iostream>
using namespace std;
struct Foo {
int a;
};
void CreateFoo(Foo** p) {
*p = new Foo();
(*p)->a = 12;
}
int main(int argc, char* argv[])
{
Foo* p = NULL;
CreateFoo(&p);
cout << p->a << endl;
delete p;
return 0;
}
This will print
12
But there are several other useful usages as in the following example to iterate an array of strings and print them to the standard output.
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
const char* words[] = { "first", "second", NULL };
for (const char** p = words; *p != NULL; ++p) {
cout << *p << endl;
}
return 0;
}
IMO most common usage is to pass reference to pointer variable
void test(int ** var)
{
...
}
int *foo = ...
test(&foo);
You can create multidimensional jagged array using double pointers:
int ** array = new *int[2];
array[0] = new int[2];
array[1] = new int[3];
One common scenario is where you need to pass a null pointer to a function, and have it initialized within that function, and used outside the function. Without multplie indirection, the calling function would never have access to the initialized object.
Consider the following function:
initialize(foo* my_foo)
{
my_foo = new Foo();
}
Any function that calls 'initialize(foo*)' will not have access to the initialized instance of Foo, beacuse the pointer that's passed to this function is a copy. (The pointer is just an integer after all, and integers are passed by value.)
However, if the function was defined like this:
initialize(foo** my_foo)
{
*my_foo = new Foo();
}
...and it was called like this...
Foo* my_foo;
initialize(&my_foo);
...then the caller would have access to the initialized instance, via 'my_foo' - because it's the address of the pointer that was passed to 'initialize'.
Of course, in my simplified example, the 'initialize' function could simply return the newly created instance via the return keyword, but that does not always suit - maybe the function needs to return something else.
If you pass a pointer in as output parameter, you might want to pass it as Foo** and set its value as *ppFoo = pSomeOtherFoo.
And from the algorithms-and-data-structures department, you can use that double indirection to update pointers, which can be faster than for instance swapping actual objects.
A simple example would be using int** foo_mat as a 2d array of integers.
Or you may also use pointers to pointers - lets say that you have a pointer void* foo and you have 2 different objects that have a reference to it with the following members: void** foo_pointer1 and void** foo_pointer2, by having a pointer to a pointer you can actually check whether *foo_pointer1 == NULL which indicates that foo is NULL. You wouldn't be able to check whether foo is NULL if foo_pointer1 was a regular pointer.
I hope that my explanation wasn't too messy :)
Carl: Your example should be:
*p = x;
(You have two stars.) :-)
In C, the idiom is absolutely required. Consider the problem in which you want a function to add a string (pure C, so a char *) to an array of pointers to char *. The function prototype requires three levels of indirection:
int AddStringToList(unsigned int *count_ptr, char ***list_ptr, const char *string_to_add);
We call it as follows:
unsigned int the_count = 0;
char **the_list = NULL;
AddStringToList(&the_count, &the_list, "The string I'm adding");
In C++ we have the option of using references instead, which would yield a different signature. But we still need the two levels of indirection you asked about in your original question:
int AddStringToList(unsigned int &count_ptr, char **&list_ptr, const char *string_to_add);
Usually when you pass a pointer to a function as a return value:
ErrorCode AllocateObject (void **object);
where the function returns a success/failure error code and fills in the object parameter with a pointer to the new object:
*object = new Object;
This is used a lot in COM programming in Win32.
This is more of a C thing to do, in C++ you can often wrap this type of system into a class to make the code more readable.

const char *const changes because of a string (?)

Hello i am building a project and today after 500 lines of code i am going to shoot my self. Today i started a new class and some very strange things are happening:
class Target {
public:
Target(const int port);
virtual ~Target();
private:
const char* initialize_port(const int port) const;
const char *const port;
};
and cpp file:
Target::Target(const int port)
:
port(initialize_port(port))
{
cout<<this->port<<endl; //this cout 80
string test3="Target2";//when i replace with char * test3="Target2" then both couts in the constructor are working ok.
cout<<this->port<<endl; //this cout Target2!!!!!!
}
const char* Target::initialize_port(const int port) const {
string port_str = std::to_string(port);
const char* port_char=port_str.c_str();
return port_char; // OR/and when i replace with something like return "80" then both couts in the constructor are working ok.
}
Target::~Target() {
}
Like you can see in the cpp file, while the default constructor is being called it couts the "this->port", then i create a string, and then i print it again. How is it even possible to get a different response??
From netbeans:
80
Target2
RUN FINISHED; exit value 0; real time: 20ms; user: 0ms; system: 0ms
PS:When in the function initialize_port(const int port) i am giving a standard return, for example return "80"; everything is ok. When in the constructor i am replacing the string with char *, again everything is ok.
PS2:I know that i have some problems with my RAM. If someone will compile and there is no problem with the outputs (cout) please let me know.
Thanks in advance.
The problem comes from:
{
string port_str = std::to_string(port);
const char* port_char=port_str.c_str();
return port_char;
}
When the return happens, port_str is destroyed because it is a locale variable to that code block. Then port_char is a dangling pointer (a pointer that used to point to an object that has now been destroyed).
Using that pointer causes undefined behaviour and that explains your weird effects when you use the pointer.
To fix this, stop using raw pointers. The simplest fix is to use std::string instead.
The problem is that the return value of port_str.c_string() is only valid for the lifetime of port_str. Since that is allocated on the stack in initialize_port it becomes invalid once that function returns.
In your constructor, when you initialize the test3 string it ends up (mostly by chance) occupying the same memory as port_str did.
If you need to use a const char * you will need to allocate new memory for the string inside initialize_port (and deallocate it in your constructor!). Alternatively just stick with using std:string objects.

C++ array passed into function

I have an object named thingy with a method playWithString(char* text).
I have a character array such as
char testString = nullptr;
I want to pass testString into thingy.playWithString(char text)
I initially tried this by putting this at the start of the playWithString method
text = new char[128]
This works fine in the function, but once the function has ended testString is null again. How do I make it retain the value of the function result?
You need to pass by reference here. This is what is happening:
void playWithString (char* myptr) {
myPtr = new char [128];
//myPtr is a local variable and will not change the fact that testString still points to NULL
*myPtr = 'a';
*myPtr = 'b';
}
main () {
char *testString = NULL; //testString is not pointing to anything
playWithString(testString);
//tesString is still null here
}
To solve this: Pass by reference. Notice the & in signature of playWithString.
void playWithString (char* &myptr) {
myPtr = new char [128];
//myPtr is a local variable and will not change the fact that testString still points to NULL
*myPtr = 'a';
*myPtr = 'b';
}
main () {
char *testString = NULL; //testString is not pointing to anything
playWithString(testString);
//tesString is still null here
}
It sounds like you are attempting to modify the pointer, not the data to which the pointer is pointing. When you create a function, the parameters are ordinarily passed by value unless you make the parameter a pointer or a reference. This means that the parameters are copied and thus assignment to the parameter only modifies a copy, not the original object. In the case where the parameter is a pointer (array parameters are represented as a pointer to the first element in the array), the pointer is being copied (although the content to which it points is the same both outside and inside the function). With this pointer, you can modify the content to which it points and have the effect persist outside of the function; however, modifying the pointer itself (e.g. to make it point to a different array) is only modifying the copy; if you want such a mutation to last outside the function, you need an extra layer of indirection. In other words, you need to pass a pointer or reference to the pointer to be able to change its target.
P.S. As others have noted, for using strings, you really should use an std::string. That being said, it's good to understand the underlying mechanics and how to use char* when learning.
Maybe you should use c++ strings (std::string) ?
#include <string>
#include <iostream>
class A {
public:
void foo(const std::string& s) {
std::cout << s << std::endl;
}
};
int main(int argc, char* argv[]) {
A a;
std::string str = "Hello!";
a.foo(str);
return 0;
}

How can I get a block of memory from a function and write it to a file?

I want to write the data "somebytes" that I get from a function called NextUnit() to a file named "output.txt", but the code that I wrote does not work. When I open the file, it does not look like my "somebytes". Here is the code:
#include <stdio.h>
#include <string.h>
char* NextUnit()
{
char Unit[256];
strcpy(Unit,"somebytes");
return &Unit[0];
}
int main()
{
FILE *ourfile;
ourfile=fopen("output.txt","wb");
char* somedata;
somedata=NextUnit();
printf("%s\n",somedata);
fwrite(somedata,1,strlen(somedata),ourfile);
fclose(ourfile);
}
You are returning the local address from a function (aka released stack address). Which is then changed once you call the next function.
Ether just return a global constant
const char* NextUnit() { return "somebytes"; }
or copy it into a new memory structure, which you will then need to also free later...
char* NextUnit()
{
char* newstr = new char[256];
strcpy(newstr,"somebytes");
return newstr;
}
// some code later
char* tmpstr = NextUnit();
// do writing stuff
// free memory
delete tmpstr;
You've declared Unit[256] on the stack in a subprocedure. But when your NextUnit() returns, the variable that was scoped to it goes out of scope, and you are no longer pointing to valid memory.
Consider allocating the memory with new, and then releasing it in the caller, or having the caller pass down a pointer to preallocated memory.
you are returning the local address of
a function. Ether just return
const char* NextUnit() { return
"somebytes"; }
so it's constant, or copy it into a
new memory stucture, which you will
then need to also free later...
I don't have enough mojo to comment on the quoted answer, so I have to put this as a new answer.
His answer is trying to say the right thing, but it came out wrong.
Your code is returning the address of a local variable inside the NextUnit() function. Don't do that. Its bad. Do what he suggested.
If you are using C++, the following is a much better way to go about this:
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char ** argv)
{
ofstream outFile;
outFile.open("output.txt");
outFile << "someBytes";
outFile.close();
return 0;
}
And, once you are comfortable with that, the next thing to learn about is RAII.
I would rewrite it like this:
char *NextUnit(char *src)
{
strcpy(src, "somebytes");
return src;
}
This way you can decide what to do with the variable outside the function implementation:
char Unit[256];
char *somedata = NextUnit(Unit);
NextUnit returns the address of Unit, which is an array local to that function. That means that it is allocated on the stack, and "released" when the function returns, making the return value non-valid.
To solve this problem you can:
Dynamically allocate a new string each time NextUnit is called. Note that in that case you will have to delete the memory afterwards.
Create a global string. That's fine for a small "test" application, but generally use of global variables is discouraged.
Have main allocate a string (either dynamically or on the stack), pass it as a parameter to NextUnit, and have NextUnit copy to that string.
You have a few problems here. The main one, I think, is that NextUnit() is allocating the buffer on the stack and you're effectively going out of scope when you try to return the address.
You can fix this in a C-style solution by mallocing space for the buffer and returning the pointer that malloc returns.
I think a first step might be to rewrite the code to something more like the following:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* NextUnit()
{
char *Unit = (char *)malloc( 256 );
memset(Unit, 0, sizeof(Unit));
strcpy(Unit,"somebytes");
return Unit;
}
int main()
{
FILE *ourfile;
ourfile=fopen("output.txt","wb");
char* somedata;
somedata=NextUnit();
printf("%s\n",somedata);
//fwrite(somedata,1,strlen(somedata),ourfile);
fprintf(ourfile, somedata);
free(somedata);
fclose(ourfile);
}
"Unit" declared as a local variable inside NextUnit which is actually a "stack" variable meaning that it's lifetime is only as long as NextUnit hasn't returned.
So, while NextUnit hasn't returned yet, copying "somebytes" to it is ok, as is printing it out. As soon as NextUnit returns, Unit is released from the stack and the pointer somedata in main will not be pointing to something valid.
Here is quick fix. I still don't recommend writing programs this way this way, but it's the least changes.
#include <stdio.h>
#include <string.h>
char Unit[256];
char* NextUnit()
{
strcpy(Unit,"somebytes");
return &Unit[0];
}
int main()
{
FILE *ourfile;
ourfile=fopen("output.txt","wb");
char* somedata;
somedata=NextUnit();
printf("%s\n",somedata);
fwrite(somedata,1,strlen(somedata),ourfile);
fclose(ourfile);
}
That works but it's kindof pointless returning the address of Unit when it's actually Global!
Declare Unit as static:
char* NextUnit()
{
static char Unit[256];
strcpy(Unit,"somebytes");
return &Unit[0];
}
But if you use C++ compiler you should consider using std::string instead of char*. std::string is more safe and will do all allocation/deallocation jobs for you.

To what use is multiple indirection in C++?

Under what circumstances might you want to use multiple indirection (that is, a chain of pointers as in Foo **) in C++?
Most common usage as #aku pointed out is to allow a change to a pointer parameter to be visible after the function returns.
#include <iostream>
using namespace std;
struct Foo {
int a;
};
void CreateFoo(Foo** p) {
*p = new Foo();
(*p)->a = 12;
}
int main(int argc, char* argv[])
{
Foo* p = NULL;
CreateFoo(&p);
cout << p->a << endl;
delete p;
return 0;
}
This will print
12
But there are several other useful usages as in the following example to iterate an array of strings and print them to the standard output.
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
const char* words[] = { "first", "second", NULL };
for (const char** p = words; *p != NULL; ++p) {
cout << *p << endl;
}
return 0;
}
IMO most common usage is to pass reference to pointer variable
void test(int ** var)
{
...
}
int *foo = ...
test(&foo);
You can create multidimensional jagged array using double pointers:
int ** array = new *int[2];
array[0] = new int[2];
array[1] = new int[3];
One common scenario is where you need to pass a null pointer to a function, and have it initialized within that function, and used outside the function. Without multplie indirection, the calling function would never have access to the initialized object.
Consider the following function:
initialize(foo* my_foo)
{
my_foo = new Foo();
}
Any function that calls 'initialize(foo*)' will not have access to the initialized instance of Foo, beacuse the pointer that's passed to this function is a copy. (The pointer is just an integer after all, and integers are passed by value.)
However, if the function was defined like this:
initialize(foo** my_foo)
{
*my_foo = new Foo();
}
...and it was called like this...
Foo* my_foo;
initialize(&my_foo);
...then the caller would have access to the initialized instance, via 'my_foo' - because it's the address of the pointer that was passed to 'initialize'.
Of course, in my simplified example, the 'initialize' function could simply return the newly created instance via the return keyword, but that does not always suit - maybe the function needs to return something else.
If you pass a pointer in as output parameter, you might want to pass it as Foo** and set its value as *ppFoo = pSomeOtherFoo.
And from the algorithms-and-data-structures department, you can use that double indirection to update pointers, which can be faster than for instance swapping actual objects.
A simple example would be using int** foo_mat as a 2d array of integers.
Or you may also use pointers to pointers - lets say that you have a pointer void* foo and you have 2 different objects that have a reference to it with the following members: void** foo_pointer1 and void** foo_pointer2, by having a pointer to a pointer you can actually check whether *foo_pointer1 == NULL which indicates that foo is NULL. You wouldn't be able to check whether foo is NULL if foo_pointer1 was a regular pointer.
I hope that my explanation wasn't too messy :)
Carl: Your example should be:
*p = x;
(You have two stars.) :-)
In C, the idiom is absolutely required. Consider the problem in which you want a function to add a string (pure C, so a char *) to an array of pointers to char *. The function prototype requires three levels of indirection:
int AddStringToList(unsigned int *count_ptr, char ***list_ptr, const char *string_to_add);
We call it as follows:
unsigned int the_count = 0;
char **the_list = NULL;
AddStringToList(&the_count, &the_list, "The string I'm adding");
In C++ we have the option of using references instead, which would yield a different signature. But we still need the two levels of indirection you asked about in your original question:
int AddStringToList(unsigned int &count_ptr, char **&list_ptr, const char *string_to_add);
Usually when you pass a pointer to a function as a return value:
ErrorCode AllocateObject (void **object);
where the function returns a success/failure error code and fills in the object parameter with a pointer to the new object:
*object = new Object;
This is used a lot in COM programming in Win32.
This is more of a C thing to do, in C++ you can often wrap this type of system into a class to make the code more readable.