Syntax for std::fread :
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
we can call std::fread with a character pointer and get the read data with the same character pointer.
eg:
char* data;
fread(data,5,10,file);
What i tried is to create a similar function which accepts a character pointer as a void* pointer.
#include <iostream>
#include<string.h>
using namespace std;
void modify(void* ptr)
{
char* temp = new char[50];
strcpy(temp,"testing");
__ptr=(void*)temp;
std::cout<<"__ptr="<<(char*)__ptr<<endl;
}
int main()
{
char* str;
modify(str);
cout<<"str="<<str;
return 0;
}
I tried the above code with http://www.compileonline.com/compile_cpp11_online.php and I got the output as
__ptr=testing
str=
(a)Why str is not printing the string "testing"?
I am assigning the address of a dynamically allocated variable to ptr.
So the value "testing" must be available in the heap even after the control returns from the method.
(b)How can i modify the function so that i will get the output as
__ptr=testing
str=testing
But function prototype cannot be modified.
Please help.
Hope the question is clear.
The problem is that the function modify() takes a reference to a void* but you are actually passing a char*. This is not valid C++ and should not compile.
That said, there are some old C++ compilers out there (Visual C++ 6?) that have a kind of extension, that allows you to do that. That is when you are calling modify(str), the compiler is creating a temporary value of type void* and initializing it to the value of str. Then the temporary is passed to the function and taking the address of the allocated memory. But, obviously, the str original value is never modified, so it remains uninitialized.
That's the main reason why the original C++ rule forbidding this is there: to protect you from this kind of bugs.
You have two solutions:
Declare the function with the proper pointer type: void modify(char*& ptr).
Change the compiler!
If you really wanted the function as is you could call it with modify(reinterpret_cast<void*&>(str)) but I do not recommend that!
By the way, never name your identifier with two underscores (__ptr) these names are reserved for the compiler writers only·
Ah! I understand now the OP problem: his idea is to write a wrapper to fread that allocates memory, reads into it from a file and returns the pointer. It is easier if you just return the pointer the usual way. Using your modify() simplified example:
void* modify()
{
char* temp = new char[50];
strcpy(temp,"testing");
return temp;
}
And then, to call it:
char *ptr = static_cast<char*>(modify());
From the valuable answer and comments from #rodrigo, i was able to solve my problem.
I modified the function.
void modify(void* ptr)
{
char* temp;
temp = (char *)ptr;
strcpy(temp,"testing");
}
This solved all the issues!
Related
Here is my program :
#include <cstring>
const int SIZE =10;
int main()
{
char aName [SIZE]; // creates an array on the stack
std::strcpy(aName, "Mary");
return 0;
}
This program is obviously useless, I am just trying to understand the behavior of the strcpy function.
Here is it's signature :
char * strcpy ( char * destination, const char * source )
so when I do :
std::strcpy(aName, "Mary");
I am passing by value the variable aName. I know that the aName (in the main) contains the address of the array.
So is this assertion correct : strcpy creates a local variable called destination that has as value the address of the array aName that I have created on the stack in the main function?
I am asking this because it is very confusing to me. Whenever I have encountered addresses it usually was to point to a memory allocated on the heap...
Thanks!
Whenever you encounter addresses it doesn't mean it will always point to memory allocated to heap.
You can assign the address of a variable to a pointer like this
int a=5;
int *myPtr= &a;
Now, myPtr is a pointer of type integer which points to the memory of variable which is created on stack which is a have value 5.
So, whenever you create a pointer and assign the (address of) memory using new keyword, it will allocate the memory on heap. So, if I assign the value like this it will be on stack
int *myPtr= new int[5];
So is this assertion correct : strcpy creates a local variable called destination that has as value the address of the array aName that I have created on the stack in the main function?
Yes.
Whenever I have encountered addresses it usually was to point to a memory allocated on the heap...
Yep, usually. But not always.
Pointers to non-dynamically-allocated things are fairly rare in C++, though in C it's more common as that's the only way to have "out arguments" (C does not have references).
strcpy is a function from C's standard library.
Maybe it would help to look at an example implementation of strcpy():
char* strcpy(char* d, const char* s)
{
char* tmp = d;
while (*tmp++ = *s++)
;
return d;
}
That's really all there is to it. Copy characters from the source to the destination until the source character is null (including the null). Return the pointer to the beginning of the destination. Done.
Pointers point to memory. It doesn't matter if that memory is "stack", "heap" or "static".
Function parameters are its local variables.
In this call
std::strcpy(aName, "Mary");
the two arrays (one that is created in main with the automatic storage duration and other is the string literal that has the static storage duration) are implicitly converted to pointers to their first elements.
So you may imagine this call and the function definition the following way
std::strcpy(aName, "Mary");
// …
char * strcpy ( /* char * destination, const char * source */ )
{
char *destination = aName;
const char *source = "Mary";
// …
return destination;
}
Or even like
char *p_to_aName = &aName[0];
const char *p_to_literal = &"Mary"[0];
std::strcpy( p_to_aName, p_to_literal );
// …
char * strcpy ( /* char * destination, const char * source */ )
{
char *destination = p_to_aName;
const char *source = p_to_literal;
// …
return destination;
}
That is within the function its parameters are local variable of pointer types with the automatic storage duration that are initialized by pointers to first characters of the passed character arrays
So is this assertion correct : strcpy creates a local variable called destination that has as value the address of the array aName that I have created on the stack in the main function?
Yes. That is correct. Though I probably wouldn't call it a local variable. It is a parameter. Local variable usually means something like this:
int localVariable;
The word'parameter" is often associated with things like this:
int myFunction(int parameter) {
// use parameter some where...
}
The point is roughly the same though: it creates a variable that will go out of scope once the function exits.
I am asking this because it is very confusing to me. Whenever I have encountered addresses it usually was to point to a memory allocated on the heap...
Yes, this is the most common use case for them. But it isn't their only use. Pointers are addresses, and every variable has an address in memory regardless of whether it is allocated on the "heap" or "stack."
The use here probably because pointers to a char are commonly used to store strings, particularly on older compilers. That combined with the fact that arrays "decay" into pointers, it is probably easier to work with pointers. It is also certainly more backwards compatible to do it this way.
The function could have just as easily used an array, like this:
char * strcpy ( char destination[], const char source[ )
But I'm going to assume it is easier to work with pointers here instead (Note: I don't think you can return an array in C++, so I'm still using char *. However, even if you could, I would imagine it is still easier to work with pointers anyway, so I don't think it makes a lot of difference here.).
Another common use of pointers is using them as a way to sort of "pass by reference":
void foo(int * myX) {
*myX = 4;
}
int main() {
int x = 0;
foo(&x);
std::cout << x; // prints "4"
return 0;
}
However, in modern C++, actually passing by reference is preferred to this:
void foo(int & myX) {
myX = 4;
}
int main() {
int x = 0;
foo(x);
std::cout << x; // prints "4"
return 0;
}
But I bring it up as another example to help drive the point home: memory allocated on the heap isn't the only use of pointers, merely the most common one (though actually dynamically allocated memory has been mostly replaced in modern C++ by things like std::vector, but that is beside the point here).
I know that the aName (in the main) contains the address of the array.
You knew wrong. aName is an array. It contains the elements, not an address.
But when you use the name of the array as a value such as when passing it to strcpy, it is implicitly converted to a pointer to first element of the array (the value of a pointer is the memory address of the pointed object). Such implicit conversion is called decaying.
So is this assertion correct : strcpy creates a local variable called destination that has as value the address of the array aName that I have created on the stack in the main function?
This is correct enough. To clarify: It is a function argument rather than a local variable. But the distinction is not important here. Technically, it is the caller who is responsible for pushing the arguments onto the stack or storing them into registers, so it could be considered that main "creates" the variable.
Whenever I have encountered addresses it usually was to point to a memory allocated on the heap
Pointers are not uniquely associated with "heap". Pretty much any object can be pointed at, whether it has dynamic, static or automatic storage or even if it is a subobject.
int FunctionName(const char *pValueName, const char *pValueData, long iMaxValueSize)
{
char *pDataToStore = const_cast<char *>(pValueData);
int iActualSiz = ProcessData(pDataToStore, iMaxValueSize);
...
...
}
In the upper code snippet ProcessData() function modifies the char*, which it receives as parameter. Now even after assigning pValueData into pDataToStore, after ProcessData() get executed, value of pValueData is being same as pDataToStore.
My aim is to keep intact value of pValueData which is being passed as const char*
My aim is to keep intact value of pValueData which is being passed as
const char*
That's impossible. Passing via const means it cannot be modified, except when it was originally not constant.
Example:
char *ptr1 = new char[100]; // not const
char *ptr2 = new char[100]; // not const
int i = FunctionName(ptr1, ptr2, 123);
In this case, you could technically keep the const_cast. But what for? Just change your function parameters to take char *:
int FunctionName(char *pValueName, char *pValueData, long iMaxValueSize)
{
int iActualSiz = ProcessData(pValueData, iMaxValueSize);
// ...
}
However, you most likely want to be able to pass constant strings. For example string literals:
int i = FunctionName("name", "data", 123);
String literals are unmodifiable and thus require your function to take char const *. A later attempt to modify them causes undefined behaviour.
As you can see, the error is in the general architecture and code logic. You want to modify something and at the same time you do not want to allow to modify it.
The question is: What happens with your pDataToStore when ProcessData is done with it? Does the caller of FunctionName need to be aware of the modifications? Or is it just internal business of FunctionName?
If it's just internal business of FunctionName, then you can keep its signature intact and have ProcessData modify a copy of the passed data. Here is a simplified (not exception-safe, no error checks) example:
int FunctionName(const char *pValueName, const char *pValueData, long iMaxValueSize)
{
char *copy = new char[strlen(pValueData) + 1];
strcpy(copy, pValueData):
int iActualSiz = ProcessData(copy, iMaxValueSize);
// ...
delete[] copy;
}
The nice thing is that you can now massively improve the interface of FunctionName by hiding all the low-level pointer business. In fact, why use so many pointers at all when C++ standard classes can do all the work for you?
int FunctionName(std::string const &valueName, std::string const &valueData, long maxValueSize)
{
std::vector<char> copy(valueData.begin(), valueData.end());
int actualSize = ProcessData(©[0], maxValueSize);
// ...
// no more delete[] needed here
}
The std::vector<char> automatically allocates enough memory to hold a copy of valueData, and performs the copy. It fully automatically frees the memory when it is no longer needed, even if exceptions are thrown. And ©[0] (which in C++11 can be written as copy.data()) is guaranteed to yield a pointer to the internally used data, so that low-level C functions can modify the vector's elements.
(I've also taken the chance to remove the Microsoft-style Hungarian Notation. It's a failed experiment from the 90s, and you've even used it incorrectly, supposing that a leading i is supposed to indicate an int.)
The bottom line is really:
If you need a const_cast anywhere in your code to make it compile, then somewhere else there is at least either one const missing or one too much. A const_cast always makes up for a mistake in another piece of code. It is always a workaround and never a solution designed up front.
Well I have solved the issue by creating the heap memory.
char *pDataToStore = new char[iMaxValueSize];
memcpy(pDataToStore, pValueData, iMaxValueSize*sizeof(char));
int iActualSiz = ProcessData(pDataToStore, iMaxValueSize);
...
....
delete []pDataToStore;
You have to make a difference between a const qualified type and a const qualified object.
The standard states in section 7.1.6.1: cv-qualifiers: (cv = const or volatile)
A pointer or reference to a cv-qualified type need not actually point
or refer to a cv-qualified object, but it is treated as if it does; a
const-qualified access path cannot be used to modify an object even if
the object referenced is a non-const object and can be modified
through some other access path.
If your pointer points to a non const object, the casting away will enable you to modifiy the objet, but as someone told, you are lying to the user of your function.
It your pointer points to a real const object (i.e. in const protected memory), the compiler will compile your code, but you might have a segmentation fault, typical for undefined behaviour.
Here an example, using the fact that "Ordinary string literal (...) has type “array of n const char”, where n is the size of the string (...)" (see standard, section 2.14.5):
char *my_realconst = "This is a real constant string"; // pointer does not claim that it points to const object
(*my_realconst)++; // Try to increment the first letter, will compile but will not run properly !!
So if your function ProcessData() is legacy code that is only reading the data but has forgotten to mention a const in the parameter list, your cast-away will work. If your function is however altering the data, it might work or it might fail, depending how the data poitned to was created !
So try to avoid casting const away if you are not 100% sure of what the effects will be ! Better clone your object the hard way creating a temporary object and copying the content.
I propose you a small template to handle these kind of issues easily:
template <typename T>
class Buffer {
size_t sz; // size
T* addr; // pointed
public:
Buffer(const T*source, size_t l) : sz(l), addr(new T[l]) { std::copy(source, source + l, addr); } // allocate and copy
~Buffer() { delete[]addr; } // destroy memory
operator T* () { return addr; } // convert to pointer
};
You may use your existing code almost as is:
Buffer<char> pDataToStore(pValueData, iMaxValueSize); // create the automatic buffer
int iActualSiz = ProcessData(pDataToStore, iMaxValueSize); // automatic use of pointer to buffer
cout << "modified copy: " << pDataToStore << endl;
cout << "original: " << pValueData << endl;
The buffer will be automatically released once pDataToStore is no longer in scope.
If you have similar issues with wchar_t buffers or anything else, it will work as well.
For explanations on the evil of casting away const, see my other answer
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C++ deprecated conversion from string constant to 'char*'
I want to pass a string via char* to a function.
char *Type = new char[10];
Type = "Access"; // ERROR
However I get this error:
error: deprecated conversion from string constant to 'char*'
How can I fix that?
If you really want to modify Type:
char *Type = new char[10];
strcpy( Type, "Access" );
If you don't want to modify access:
const char *Type = "Access";
Please note, that, however, arrays of char in C and in C++ come with a lot of problems. For example, you don't really know if the call to new has been successful, or whether it is going to throw an exception. Also, strcpy() could surpass the limit of 10 chars.
So you can consider, if you want to modify type later:
std::string Type = "Access";
And if you don't want to modify it:
const std::string Type = "Access";
... the benefit of using std::string is that it is able to cope with all these issues.
There are a couple of things going on here.
char *Type = new char[10];
This create a char* pointer named Type and initializes it to point to the first element of a newly allocated 10-element array.
Type = "Access"; // ERROR
This assignment doesn't do what you think it does. It doesn't copy the 6-character string "Access" (7 characters including the terminating '\0') to the array you just created. Instead, it assigns a pointer to the first element of that array into your pointer Type. There are two problems with that.
First, it clobbers the previous value of Type. That 10-character array you just allocated now has nothing pointing to it; you can no longer access it or even deallocate it. This is a memory leak.
This isn't what the compiler is complaining about.
Second, a string literal creates a statically allocated const array ("statically allocated" meaning it exists for the entire execution of your program). Type is not declared with a const qualifier. If the compiler allowed you to point Type to the string "Access", you could use that pointer to (attempt to) modify it:
Type = "Access";
Type[0] = 'a'; // try to change the string to "access"
The purpose of const is to prevent you from modifying, or even attempting to modify, things that are read-only. That's why you're not allowed to assign a non-const pointer value to a const pointer object.
Since you're programming in C++, you're probably better off using std::string.
I want to pass a string via char* to a function.
Here is how you can pass a string via char* to a function (note the required const keyword in the function signature.)
#include <iostream>
void f(const char* p) {
std::cout << p << "\n";
}
int main() {
f("Access");
}
But, what if you are invoking an existing function, and cannot modify its signature?
If you have some external guarantee that the function will not write through its argument pointer,
#include <iostream>
void f(char* p) {
std::cout << p << "\n";
}
int main() {
f(const_cast<char*>("Access"));
}
If, on the other hand, the function might write to the string, then you'll need to allocate space for the string:
#include <iostream>
void f(char* p) {
*++p;
std::cout << p << "\n";
}
int main() {
// Allocate read-write space on the heap
char *p = new char[strlen("Access"+1)];
// Copy string to allocated space
strcpy(p, "Access");
f(p);
delete p;
}
or,
#include <iostream>
void f(char* p) {
*++p;
std::cout << p << "\n";
}
int main() {
// Allocate read-write space on the stack
char arr[] = "Access";
f(arr);
}
But, the best course by far is to avoid the whole pointer mishegas:
#include <iostream>
void f(const std::string& p) {
std::cout << p << "\n";
}
int main() {
f("Access");
}
You've got a basic operations problem here, not a coding issue.
When you want to change the contents of a C char array, you do not use the assignment operator. That will instead change the value of the underlying pointer. Ick.
Instead you are supposed to use the C string library routines. For instance, strcpy (Type, "Access"); will copy the string literal "Access" into your character array, with its all-important trailing nul character.
If you are using C++ (as your tags indicate), you should probably be using std::string instead of arrays of char. Assignment works they way you are expecting there.
I am writng a c++ program. I am parsing a file and initializing a structure. I have an array to initialize but I have to read the size of the array from the file. I want the array length read and array initialization in one function. If I pass the array pointer to another function and do a new, when the function returns, the pointer is destroyed, and I cannot see the initialized values. Is this expected or am I missing something. How can I overcome this problem?
You overcome this by forgetting everything about manual arrays, raw pointer passing* and new. This is C++, not 1991. So, a typical solution could be this:
#include <vector>
#include <cstdint>
#include <istream>
std::vector<uint32_t> read_data(std::istream & is)
{
uint32_t len;
is.read(reinterpret_cast<char*>(&len), sizeof(uint32_t));
std::vector<uint32_t> result(len);
for (uint32_t i = 0; i != len; ++i)
{
is.read(reinterpret_cast<char*>(&result[i]), sizeof(uint32_t));
}
return result;
}
(In high-quality code, the read commands would be surrounded by a conditional and errors would be handled, possibly by throwing an exception.)
Later:
#include "int_reader.hpp"
#include <fstream>
#include <iostream>
int main()
{
std::ifstream infile("thedata.bin", std::ios::binary);
std::vector<uint32_t> data = read_data(infile);
std::cout << "We read " << data.size() << " integers.\n";
}
*) The only raw pointer that has a place in general-purpose C++ is a char* when used for I/O operations, as demonstrated by this code. C++ defined char to be the machine's fundamental data unit type, and I/O happens in units of char.
There is no array pointer before you call new. So there's no way you could pass it to a function.
Likely what you're doing is passing the uninitialized, garbage value of the array pointer to a function. The function overwrites its copy of that garbage value with the correct pointer returned from new, but then the original function never sees that pointer.
You need to pass the function a pointer to the pointer. Then when it calls new, it can use the pointer to the pointer to update the caller's pointer. Like this:
void SomeFunction(void **SomePointer)
{
(*SomePointer) = malloc(1024);
}
void *MyPointer;
SomeFunction(&MyPointer);
You have to pass a pointer to a pointer in order to have a function allocate it for you
void allocateArrayOfT(T** objArray, size_t len) {
*objArray = new T[len];
}
You can call:
T* arrayPtr;
allocateArrayOfT(&arrayPtr, len);
This is just a simple question. I've been reading the source of something which attaches to a memory address of a subroutine using DetourAttach(&(PVOID &)BindKeyT, BindKeyD); where BindKeyT is the address to a subroutine in memory. I'm curious, what exactly does (&(PVOID &) mean in english? I understand that PVOID is a void pointer, but how does this get translated into a function which can be used to attach a detour to?
Terry Mahaffey is right, what you are passing is a pointer to a pointer to the function. This is commonly used whenever the function you are passing the pointer to (in this case, DetourAttach) wants to return more than one value, and one of those returned values is a pointer. Since functions in C/C++ can only return a single value, the only way to obtain multiple values from them is via pointers.
A simple example would be when one wishes to return a pointer to a block of allocated memory. Then one can write a function like:
int allocstr(int len, char **retptr)
{
char *p = malloc(len + 1); /* +1 for \0 */
if(p == NULL)
return 0;
*retptr = p;
return 1;
}
To answer your other question, of how to setup a memory address to be used as a function, one can do it like so:
void* (void * BindKeyT)(const char* key) = actual_BindKeyT;
// actual_BindKeyT is a pointer to a function that will be defined elsewhere,
// and whose declaration you will include in your project through a header file
// or a dll import
void * BindKeyD(const char* key)
{
// Code for your hook function
}
DetourAttach(&(PVOID&)BindKeyT, BindKeyD);
(taken from http://zenersblog.blogspot.com/2008/04/api-hooking-with-detours-part-1.html)
Bear in mind that the declarations for BindKeyT and BindKeyD should match.
The C++ parser in my head (which is not bug free) says that it is a C style cast of BindKeyT to a reference to a pointer to void - the (PVOID&) part - and then taking the address of that - the & in front. So the result of the expression is a pointer to a pointer to the function.
There is an introduction to Detours here: api-hooking-with-detours-part-1