Reputation: 793
I know this is really easy and I'm looking over something but this is what I have...:
typedef struct
{
char s1[81];
char s2[81];
char s3[81];
}Rec;
int main()
{
Rec *a[10];
a[0] = (Rec*)new unsigned char(sizeof(Rec));
a[0]->s1= "hello";
printf("a[0] = %s\n",a[0]->s1);
delete(a[0]);
getchar();
return 0;
}
Now, the line
a[0]->s1= "hello";
is complaining about the expression must be a modifiable lvalue. I am pretty sure it's how I'm casting it in my new operator line and has it needs to be a long value or something but I'm not sure of the code to do this... easy i know but yeah. Any help would be much appreciated
Upvotes: 0
Views: 102
Reputation: 36985
I guess that you've done a lot of C in your life. Keep in mind that C++ is different language, which happen to share with C most of its syntax and some of its standard library. That means something that is perfectly fine in C might be quite ugly (or even dangerous) in C++.
With that said, let's rewrite your code in a more "C++-ish" way:
#include <iostream> // std::cout, std::endl
#include <string> // std::string
struct Rec // typedef is implicit for structs in C++
{
std::string s1; // use std::string instead of char arrays
std::string s2;
std::string s3;
}; // don't forget the semicolon!
int main()
{
Rec * a[10];
a[0] = new Rec; // allocates the right amount of memory, no need to cast
a[0]->s1 = "hello"; // std::sring handles the assignment for you
std::cout << "a[0] = " << a[0]->s1 << std::endl; // use iostreams
delete a[0]; // delete is an operator, not a function, no need for parentheses
getchar(); // warning, this is not portable
return 0;
}
As you see, new
is not an "improved malloc
". It's typesafe (no cast needed), it's safer to use (it allocates the exact amount of memory required, no need for sizeof
), and it also does something that malloc
cannot do: it invokes the class' constructor (just as delete
invokes a destructor).
In C++, as in C, allocation is distinct from initialization. While in C you could just memset
the block to zero, in C++ object construction can be a bit more complex. As such, you should never use malloc
to create objects of classes that have non-trivial constructors (or have fields that don't have non trivial constructors - Rec
is such a case). Because new
always works, and has additional features, you should use it anyway.
Upvotes: 1
Reputation: 32635
Two things. The line
a[0] = (Rec*)new unsigned char(sizeof(Rec));
allocates a single unsigned char
that gets initialized to the value sizeof(Rec)
. You probably meant
a[0] = (Rec*)new unsigned char[sizeof(Rec)];
or better yet
a[0] = new Rec;
Second, you cannot assign a string literal to an array of chars, you need to copy the characters one by one, e.g.
char s[80];
s = "hello"; // won't work
strcpy(s, "hello"); // correct
You should however use std::string
in this case.
Upvotes: 3
Reputation: 2937
a[0] is a pointer to an array of chars that can't be modified -- a[0] will always point to the same address. you need to use strcpy to copy from your "hello" string to a[0]
Upvotes: 0
Reputation: 81379
The problem is not with your casting. Your new expression allocates a single unsigned char
and initializes it to the sizeof(Rec)
instead of allocating enough space as new unsigned char[sizeof(Rec)];
would do. That said, the types of s1
and "hello"
are different and you can't assign one with the other. You should be using something like strcpy
, but since you tagged this C++ then you would be better off using std::string
. Also, why don't you just call new Rec;
?
Upvotes: 0
Reputation: 103733
You cannot assign to char arrays like that. Either use strcpy, or change your char arrays to std::string
.
strcpy(a[0]->s1, "hello");
Why are you doing this:
a[0] = (Rec*)new unsigned char(sizeof(Rec));
instead of this:
a[0] = new Rec;
Upvotes: 5