Dynamically allocated string - c++

I have defined a struct that stores the length and content of a string.
struct sir {
int length;
char* string;
};
I am trying to dynamically alocate memory space for this string using:
s->string = malloc(sizeof(char) * (s->length));
But I keep getting this error:
error C2440: '=' : cannot convert from 'void *' to 'char *'
Can you please guide in finishing this function?
PS: I would really like to know how write values from keyboard in this newly created string?
Tnx in advance!

malloc() will return void *, which needs to be converted to char * explicitly in C++ (though not needed in C).
Try
s->string = (char *) malloc(sizeof(char) * (s->length));
Edit: As you're using C++, as #chris commented, you should consider to use std::string instead. No manual memory management is needed. If you must do it yourself, use new instead of malloc.

You are compiling the program as a C++ program. The return type of function malloc is void * However a pointer to void may not be implicitly converted to a pointer to other type in C++ and the error message says about this clear enough.
So write
s->string = ( char * )malloc(sizeof(char) * (s->length));.
However the coorect way is to use operator new instead of malloc in C++
s->string = new char[s->length];.
Again if it is a C++ program then instead of the structure it would be better to use a class with explicitly defined constructors, destructor and the copy bassignment operator.
Or compile your program as a C program if you indeed want to deal with a C program.

Related

How do I create an array of pointers in c++

I'm trying to create an array of pointers using my professors example in class. I can't seem to get it to work though.
char * ISBN[] = {
"1-214-02031-3",
"0-070-21604-5",
"2-14-241242-4",
"2-120-12311-x",
"0-534-95207-x",
"2-034-00312-2",
"1-013-10201-2",
"2-142-1223",
"3-001-0000a-4",
};
This is my professors example of declaring an array of pointers of type char. He says this is what we should do for the assignment. Sadly, I'm getting the error -
Error (active) E0144 a value of type "const char *" cannot be used to initialize an entity of type "char *" -
I've asked about this before and someone said that char * has been deprecated. But the professor says that this is the declaration that we should use for the assignment. How would I go about trying to figure out how to get this array working? What exactly is this declaration doing?
const char * ISBN[] = {
"1-214-02031-3",
"0-070-21604-5",
"2-14-241242-4",
"2-120-12311-x",
"0-534-95207-x",
"2-034-00312-2",
"1-013-10201-2",
"2-142-1223",
"3-001-0000a-4",
};
I guess I just needed to add const in front of char *. I still got much to learn. Thanks everyone.
It is simply because you are trying to assign string literals to char pointer.In c++ string literals are const char pointer because as string literals are stored in read-only memory.Another reason is for optimisation for compilers(storing only one instance of a literal that is repeated many times in the source). So you get multiple pointers to the same memory, instead of each occupying a separate chunk of memory.

strcpy on a string pointer gives errors

I have read a lot about the subject and I am confused .
What used to work in a C file ,not working on a cpp file :
char *builtinFunctions[20];
Then I get error on the strcpy function here :
void Intepreter::setBuiltIns(char *builtins)
{
strcpy(builtinFunctions, builtins); // no matching function call to strcpy
}
I probably don't understand the basics here, but why in C++ this will not work ( do i need to use = instead ? )
strcpy(char *, const char*) = thats the structure
if I change the builtinFunctions from being a pointer it works.
EDIT:
The reason for being a const before this edit is that I read here :
Why is conversion from string constant to 'char*' valid in C but invalid in C++
that char *builtinFunctions[20]; will produce warning when :
builtinFunctions[0]="me";
and it did. I could fix it by removing the const .
This is an array of pointers to char.
char *builtinFunctions[20];
So you call
strcpy(builtinFunctions, builtins);
gets treated as strcpy(char **, char*), not as strcpy(char *dest, const char *src). So you get a mismatch for first parameter type.
EDIT:
So let's suppose builtinFunctions is "an array of words" you wish to populate, with void Intepreter::setBuiltIns(char *builtins) meant to do just that with it's first parameter being a pointer to a new incoming word. (And you're doing this in a C-style manner. Well, up to you.)
Some things to consider.
If you declare an array type arrName[N]; then the array's name
being used all alone without index is treated as a variable of type
type *arrName. If you type is initially char *, then
builtinFunctions by itself is of type char**. That's why your
strcpy fails, but strcpy(builtinFunctions[someIndex], builtins);
works.
Before invoking strcpy you should consider, if you have a
destination space allocated. builtinFunctions[someIndex] is of
type char *. Where does it point to? Is it a valid pointer to an
allocated space, or a gateway to hell of undefined behaviour strcpy will happily take you to?

incompatible types in assignment of const char* to char [duplicate]

This question already has answers here:
C++ Error: Incompatible types in assignment of ‘char*’ to ‘char [2]
(3 answers)
Closed 9 years ago.
So I trying to build this program that will take two char and a double. Once the user has input the information. I will transfer the information to an object by using the function below.
But every time I try to compile i get this error incompatible types in assignment of const char* to char [20]. Can anyone give me a hand and clarify when im not understanding. Thanks in advance.
void Molecule::set(const char* sym, const char* type, double weighT);
And this how I call it.
molecule[i].set(symbol, description,weight);
And within the set() function I just have to transfer the values inpputed to my private member in my object which i did by using this-> function.
////So This part is supposed to transfer the value to my Class Molecule private members////
this->symbol_ = sym;
this->type_ = type;
this->weight_ = weighT;
///////Here is my Class Molecule////////
class Molecule{
private:
char symbol_[20];
char type_[20];
double weight_;
public:
void set(const char* sym, const char* type, double weighT);
void display() const;
};
You need to use strcpy or similar to copy the strings from your char * to your class's char []. Using = is attempting to copy the pointer but they are indeed incompatible types.
This code
this->symbol_ = sym;
this->type_ = type;
is invalid. Arrays have no the copy assignment operator. You should use either standard C function strcpy or strncpy that are declared in header <cstring>
For example
std::strncpy( this->symbol, sym, 20 );
this->symbol[19] = '\0';
std::strncpy( this->type, type, 20 );
this->type[19] = '\0';
Also it is a good idea to assign a name for magic number 20 either using an enumerator or static constant.
Also instead of character arrays you could use standard class std::string that has several overloaded assignment operators.
symbol_ is a char[], you need to use stcpy to fill it.
In set method :
this->symbol_ = sym;
should becomes
stncpy(this->symbol_, sym, 20);
Or simpler define symbol_ as an std::string replacing :
char symbol_[20];
with
std::string symbol_;
Pointers and Arrays are not the same thing, although it is easy to believe that they are.
Arrays can be passed as arguments to functions that request pointers because of pointer decay, and that can lead people to believe that they are interchangeable.
See this article: What is array decaying?
When you declare symbol_[20], this tells the class to allocate 20 bytes when the object is created. symbol_ will always point to this allocation. You cannot reassign it as you could with a pointer.
You probably will want to copy the text pointed to by sym using std::strncpy. Be careful, though. If the string pointed to by sym is bigger than 19 characters (19 + 1 for the null character at the end), then you will need to terminate your symbol_ array with a null character (\0) manually for it to be a valid string.
#include <cstring>
...
std::strncpy(symbol_, sym, sizeof(symbol));
symbol_[19] = '\0';
I didn't get the chance to compile the code above, so, it might be best to study the example at the end of this article:
http://www.cplusplus.com/reference/cstring/strncpy/?kw=strncpy

Looking for the shortest string type conversion C++

I'm making an unmanaged C++ DLL which uses the C# managed DLL. I'm writting the C++ library as I need to use functions and headers defined in a software for which the C++ library can be added as an addon. But the things I want to make are so complex that my sparse knowledge of C++ would slow me down so I decided to do things in my favourite C# and connect the DLLs via COM and I was successful.
I'm somehow successful in making the code work, but less successful in keeping the code concise as I'm clearly not a professional C++ programmer.
The problem is with converting various string types. BSTR and const char * in particular.
The following code converst const char * to BSTR:
BSTR bstrt;
const char * someChar;
csharpInterfacedClassPointer->get_PropertyForSomeChars(&bstrt);
strcpy_s(nstring, (char *)bstrt);
someChar = nstring;
The problem is, I have plenty of discrete someChars with corresponding discrete interface methods...the property method is generated from the C# interface so I can't change it. Each of the "someChar" requires the following three lines of code so for 30 discrete variables, I'd need to write 90 lines of code.
csharpInterfacedClassPointer->get_PropertyForSomeCharX(&bstrt);
strcpy_s(nstring, (char *)bstrt);
someCharX = nstring;
The question is: how do write some shortcut for this so it'd fit just in one line?
I tried some sort of function with the "getter" function pointer and the someChar pointer.
typedef HRESULT (__stdcall *get_string_func)(BSTR * str); //getter function pointer
//the converting function
void ConvertAndAssign(get_string_func bstr_get_fx, const char * constCharString)
{
const size_t nsize = 1000;
char nstring[nsize];
BSTR bstrt;
bstrt = bstr_t(constCharString);
bstr_get_fx(&bstrt);
strcpy_s(nstring, (char *)bstrt);
constCharString = nstring;
}
//calling the function...as I thought that would work
ConvertAndAssign(sPtr->get_DataFile, someChar);
But then the compiler says some weird things aboud bound functions and how they are not allowed as pointers...I googled what does it mean and the solutions given required to alter the function definition but I can't do that since the definition is generated from the C# code (by regasm.exe).
Important note: I need to get the const char * type in the end because it is the required input type to the functions of the program for which I'm making the C++ DLL.
Disclaimer: it was a long time (7 years to be more precise) since I have touched C++/COM code for the last time.
Regarding binding an instance method to a function pointer check this SO question.
Another option is to use the IDispatch interface (if your COM component implement it)
Regarding ConvertAndAssign() implementation, IMO it has some issues. In order to make it easier to explain I have copied it bellow:
void ConvertAndAssign(get_string_func bstr_get_fx, const char * constCharString)
{
const size_t nsize = 1000;
char nstring[nsize];
BSTR bstrt;
bstrt = bstr_t(constCharString); // issue 1
bstr_get_fx(&bstrt);
strcpy_s(nstring, (char *)bstrt); // issue 2
constCharString = nstring; // issues 3 & 4
}
if your COM method returns a BSTR (i.e, it has an out parameter of type BSTR) you should not pass on a pre-allocated string otherwise you'll end up
leaking memory.
Casting bstr to char * will not work. BSTRs are Unicode strings. Also they are encoded such its length preceeds the actual characters.
If you are using ATL/MFC you can use one of the string conversion macros.
If you are NOT using ATL/MFC you can use WideCharToMultiByte() function or one of the "Smart" BSTR classes (CComBSTR in ATL, bstr_t, etc)
Assigning nstring to constCharString will have no effect on the outside string. If you are calling ConvertAndAssign like follows
char *outsideStr = NULL;
ConvertAndAssign(whatever, outsideStr);
Inside ConvertAndAssign() function consCharString will point to NULL in the begning. After the assignment constCharString does point to nstring but
outsideStr still points to NULL (remember, when you called ConvertAndAssign() function a copy of the pointer value was passed to it).
In order to get what you want you can either pass a reference or a pointer to a pointer:
void ConvertAndAssign(get_string_func bstr_get_fx, const char * &constCharString)
{
constCharString = nstring; // Assignment
}
or a pointer to a pointer:
char *outsideStr = NULL;
ConvertAndAssign(whatever, &outsideStr);
void ConvertAndAssign(get_string_func bstr_get_fx, const char **constCharString)
{
.
.
.
*constCharString = nstring; // Assignment
}
After fixing the previous issue you'll hit another one: You cannot return the address of a local variable! When your code resumes after ConvertAndAssign() returns, this
address is not allocated for you anymore (it's part of the stack, so it may even look to be working, but I assure you, it is not; the slightest changes
in your code may break it)
To fix this you need to pass a pre-allocated string:
char outsideStr[1000];
ConvertAndAssign(whatever, outsideStr);
void ConvertAndAssign(get_string_func bstr_get_fx, const char * constCharString)
{
strcpy_s(constCharString, /* result str here */ );
}
or allocate a string in the heap.
Given all the above, one possible implementation for ConvertAndAssign() and its usage is as follow:
char outsideStr[1000];
ConvertAndAssign(whatever, outsideStr);
void ConvertAndAssign(get_string_func bstr_get_fx, const char * constCharString)
{
BSTR bstrt;
if(SUCCEEDED(bstr_get_fx(&bstrt)))
{
// Assumes constCharString points to a buffer large enough to hold the converted string.
strcpy_s(constCharString, CW2A(bstr)); // not completely correct since bstr may contain the byte 0 but I guess thats not your scenario.
SysFreeString(bstr);
}
else
{
// error handling.
constCharString[0] = 0;
}
}
This question can be deleted if any mod is going to read this. I realized I have a totally different problem. Thanks Vagaus for his effort.

Attempting to write a String constructor to handle static char * such as "Hello World"

I've got a String class. Recently, I found the poor thing couldn't handle:
String string = "Hello World";
I immediately decided to rectify this by adding a constructor. However, the exact parameter eludes me:
inline String(const char[] str) : Array(str, sizeof(str) / sizeof(char)) { }
generates the following error: "error C2146: syntax error : missing ')' before identifier 'str'"
What I'm thinking is that since it's a static char * literal, it isn't meant to be passed to a function. But, I don't actually know.
Thanks. (To reassure - Any array passed to Array will promptly be copied, not stored)
Simplest would be to take const char* as the parameter. Then use strlen to find the string length, then allocate len+1 characters using new and use strncpy to copy the string to the newly allocated memory. BTW, any specific reason not to use std::string?
You not need to use sizeof(char) - according to standard of C++ sizeof(char) always equals 1.
This particular error is generated because the square brackets [] should go after str, not after char. Change this and the error should disappear.
However, I don't think your calculation sizeof(str) / sizeof(char) will work, because when an array is used as a parameter, you lose the information regarding the length of the string. It only work if you are using the original array. The calculation you perform will be equivalent to sizeof(char *) / sizeof(char), which will not reflect the size of the string. Instead, do as Asha says and use strlen and strcpy.