Question on reuse of pointers after passing to functions - c++

So, when I pass a const char * to a function once, can I use it again? It appears to end up spitting out crap to me.
const char *config_file = "file.txt";
function(int x, config_file);
cout << "Number" << x;
secondfunction(int y, config_file);
Do I need to make another pointer to config_file?
If so, how do I do that?
Thanks!

No, your can use it just fine. Despite the fact that the code you gave is uncompilable, I think I understand what you're asking.
A code segment like:
const char *x = "Hello";
fnA (x);
fnB (x);
should be just fine.
If you find that fnB is not getting what it expects then either:
fnA is changing what x points to (normally not possible since it's a const char *); or
some unshown piece of code is changing the pointer itself; or
something is corrupting the memory.
Try this code as an example:
#include <iostream>
#include <iomanip>
static void fnA (const char *a) {
std::cout << "fnA: [" << a << "]" << std::endl;
}
static void fnB (const char *b) {
std::cout << "fnB: [" << b << "]" << std::endl;
}
int main (void) {
const char *x = "Hello";
fnA (x);
fnB (x);
return 0;
}
It outputs, as expected:
fnA: [Hello]
fnB: [Hello]

Related

How to convert a long long in const char* in c++

I tried to use a function that converts a long long to an const char* because the function socket->write in my code needs a parameter with the datatype const char *data. But if I look to my output, convertedLabel is nothing and I don't know why. I think I haven't the right converting function.
My code:
void ServerNet::sendData(long long label270) {
std::cout << "First:" << std::endl;
std::cout << label270 << std::endl;
//Error is here:
const char* convertedLabel = reinterpret_cast<char * const>(label270);
std::cout << "Then:" << std::endl;
std::cout << convertedLabel << std::endl;
socket->write(convertedLabel);
}
Output:
First:
2173457687
Then:
#include <iostream>
#include <string>
void SendData(const char* Data) {
std::cout << Data << std::endl;
}
int main() {
long long label270 = 2173457687;
SendData(std::to_string(label270).c_str());
return 0;
}
With yours guys tipps I handled the problem. Here's the solution:
void ServerNet::sendData(long long label270) {
std::string convertedLabel = std::to_string(label270);
const char *test = convertedLabel.c_str();
socket->write(test);
}
Thanks everybody!

Constant pointer modified in function

I tried compiling this code being absolutely sure it won't compile since I try to modify the address to a const pointer (int p[100]), but the code compiled and run perfectly. Can anyone explain to me why this worked?
#include <iostream>
using namespace std;
int bar1(int *p){ cout << p << " "; p++; cout << p << "\n"; return 0; }
int bar2(int p[100]){ cout << p << " "; p++; cout << p; return 0; }
int arr1[100];
int arr2[100];
int main(){
bar1(arr1);
bar2(arr2);
}
I compiled this in Visual Studio 2013 the output was:
3f320 3f324
3f4B0 3f4B4
I try to modify the address to a const pointer (int p[100])
That's not a const pointer. As a function parameter, it's equivalent to int * p.
A const pointer looks like int * const p, and your code will give the expected compile error if you use that.

return static character array by using reference

Now I want to write a new version of the following code:
const char * f() {
return "Hello";
}
const char *pf = f();
I wonder how to use reference instead of pointer.
I have one idea by using string.
Is there a more straight way to solve this?
UPDATE:
I read the answer and comments carefully. I got another idea is to treat the return value as a const char array. But this solution seems too complicated and not so clear as a pointer.
If you want to know the syntax then the definition will look the following way
#include <iostream>
const char ( & ( f() ) )[6] { return ( "Hello" ); }
int main()
{
std::cout << f() << std::endl;
}
Or as #Jarod42 advices you can use a typedef that the fiunction definition woild look simpler
#include <iostream>
const char ( & ( f() ) )[6] { return ( "Hello" ); }
typedef const char ( &Array_Ref )[6];
Array_Ref g() { return ( "Hello" ); }
int main()
{
std::cout << f() << std::endl;
std::cout << g() << std::endl;
Array_Ref s = g();
std::cout << s << std::endl;
}
If you want to use std::string then it would be better to write the function as
std::string f() { return ( "Hello" ); }

C++. Error: void is not a pointer-to-object type

I have a C++ program:
struct arguments
{
int a, b, c;
arguments(): a(3), b(6), c(9) {}
};
class test_class{
public:
void *member_func(void *args){
arguments vars = (arguments *) (*args); //error: void is not a
//pointer-to-object type
std::cout << "\n" << vars.a << "\t" << vars.b << "\t" << vars.c << "\n";
}
};
On compile it throws an error:
error: ‘void*’ is not a pointer-to-object type
Can someone explain what I am doing wrong to produce this error?
You are dereferencing the void * before casting it to a concrete type. You need to do it the other way around:
arguments vars = *(arguments *) (args);
This order is important, because the compiler doesn't know how to apply * to args (which is a void * and can't be dereferenced). Your (arguments *) tells it what to do, but it's too late, because the dereference has already occurred.
Bare bones example to reproduce the above error:
#include <iostream>
using namespace std;
int main() {
int myint = 9; //good
void *pointer_to_void; //good
pointer_to_void = &myint; //good
cout << *pointer_to_void; //error: 'void*' is not a pointer-to-object type
}
The above code is wrong because it is trying to dereference a pointer to a void. That's not allowed.
Now run the next code below, If you understand why the following code runs and the above code does not, you will be better equipped to understand what is going on under the hood.
#include <iostream>
using namespace std;
int main() {
int myint = 9;
void *pointer_to_void;
int *pointer_to_int;
pointer_to_void = &myint;
pointer_to_int = (int *) pointer_to_void;
cout << *pointer_to_int; //prints '9'
return 0;
}
You have the * in the wrong place. So you're trying dereference the void*.
Try this instead:
arguments vars = *(arguments *) (args);
std::cout << "\n" << vars.a << "\t" << vars.b << "\t" << vars.c << "\n";
Alternatively, you can do this: (which also avoids the copy-constructor - as mentioned in the comments)
arguments *vars = (arguments *) (args);
std::cout << "\n" << vars->a << "\t" << vars->b << "\t" << vars->c << "\n";
The problem as bdonlan said is "dereferencing void* before casting".
I think this example would help:
#include <iostream>
using namespace std;
int main()
{
void *sad;
int s = 23;
float d = 5.8;
sad = &s;
cout << *(int*) sad;//outputs 23//wrong: cout << *sad ;//wrong: cout << (int*) *sad;
sad = &d;
cout << *(float *) sad;//outputs 5.8//wrong: cout << *sad ;//wrong: cout << (float*) *sad;
return 0;
}
*args means "the object(value) args points to". Therefore, it can not be casted as pointer to object(argument). That's why it is giving error
The problem above there is that you are trying to deference a void pointer which is not allowed in C or C++.
However, this still works:
#include <iostream>
using namespace std;
int main()
{
int b=10;
void *a=&b;
int *ptr=(int*)a;
cout<<*ptr;;
}
We can deference int* pointers after casting void pointers to int* pointers.

how to store the content of variable into const char*?

i have a pointer or variable which stores the address like 0xb72b218 now i have to store this value in to const char*. how i can store it. Thanks in advance.
I tried following:
suppose i have a pointer variable "ptr" which contains 0xb72b218 value
ostringstream oss;
oss << ptr;
string buf = oss.str();
const char* value = buf.c_str();
but it is more complicated any one know easy way.
Well... if you really want the address of something in a string, this will do:
#include <stdio.h>
#include <iostream>
int main(){
char buf[30];
void* ptr = /*your pointer here*/;
snprintf(buf,sizeof(buf),"%p",ptr);
std::cout << "pointer as string: " << buf << "\n";
std::cout << "pointer as value: " << ptr << "\n";
}
Or if you don't like magic numbers and want your code to work even when 256bit pointers are nothing special anymore, try this:
#include <limits> // for numeric_limits<T>
#include <stdint.h> // for intptr_t
#include <stdio.h> // for snprintf
#include <iostream>
int main(){
int i;
int* ptr = &i; // replace with your pointer
const int N = std::numeric_limits<intptr_t>::digits;
char buf[N+1]; // +1 for '\0' terminator
snprintf(buf,N,"%p",ptr);
std::cout << "pointer as string: " << buf << "\n";
std::cout << "pointer as value: " << static_cast<void*>(ptr) << "\n";
}
Example on Ideone.
OK, presumably there must some additional parameter that tells the function what type of data is actually being passed, but you can do it like this:
extern void afunc(const char *p, int type);
int value = 1234;
afunc((const char *)&value, TYPE_INT);
Have you looked at const_cast? It is a means of adding/removing const-ness from a variable in C++. Take a look here.