In Borland C++ when I write this code, compiler gives this error --> "Lvalue required".
struct harf {
char word[10];
} pr[10];
void main() {
pr[0].word="Alireza"; //Lvalue required
getch();
}
What can I do?
Assignment operation is not allowed on arrays. C++ does not allow you to do that.
For copying data to a character array, use string copy function.
Use it like this.
strcpy(pr[0].word,"Alireza");
Another way to do this is to perform char by char copy using a loop yourself. Though better use library functions. :)
This question may also help you.
Iterating through C-style array not using a pointer
Remember that compound operations are not allowed on arrays in C++. You cannot directly perform arithmetic or logical operations on them.
You need to use strcpy(..) or strncpy(..). You can not directly assign it using assignment operator.
strcpy(pr[0].word,"Alireza");
Besides, since you are using C++, why not use std::string. Something like:
std::string myString;
..
myString = "AlireZa";
use :
strncpy( pr[0].word, "Alireza", 10);
slightly safier solution is to :
strncpy( pr[0].word, "Alireza", sizeof(pr[0].word)/sizeof(pr[0].word[0]));
this way if word array changes you wont have to fix size change in other parts of your code. Using strncpy is considered safier than strcpy, because the second one can easily cause buffer overrun.
Still, its better to use std::string
pr[0].word is an array. You cannot assign to arrays.
In your situation, the array expression decays to a pointer to the first element, but that expression is an rvalue (since obviously it makes no sense to attempt to change that pointer!).
pr[0].word is an array at some location in memory.
"Alireza" is another char array in some different location in memory.
Your assignment tries to redirect pr[0].word to the Alireza memory, which is invalid since pr[0].word is an array. You can redirect pointers but not arrays. You can either:
make a pr[0].word a pointer and then set the pointer to different locations as you try to do now.
Copy the contents of the "Alireza" memory to pr[0].word memory, using strcpy function as suggested by others
As you are in C++, you can also declare pr[0].word as a std::string which will do all memory-copy the magic for you under a convenient = operator, making pr[0].word="Alireza" valid again. This approach may also help you avoid some nasty bugs which could otherwise occur when dealing with "naked" char *.
Related
Is the name of a vector simply a pointer, just like a vanilla C array?
Thus, I could send the address to a single piece of non-vector data (a pointer, in other words) to a function argument that expects a vector since a vector is also a pointer.
For example, a function that is declared as this:
void RenderingEngine::Render(const vector<Visual>& visuals) const{
Could be called like this:
Visual visual; // is NOT a vector
//do stuff with visual
m_renderingEngine->Render(&visual);
Makes sense and is valid, legal C++?
This example code is from an O'Reilly C++ book, so I guess it is an error in the book.
Is the name of a vector simply a pointer, just like a vanilla C array?
No. It's a fully-formed class.*
* What's more, a vanilla C array is not a pointer either (it just get turns into one in most situations).
No. That doesn't make sense. There is no implicit conversion from T* to std::vector<T>.
But in C++11, you can do something which is very close1 to what you're doing. You could create the vector on the fly while passing the argument as:
m_renderingEngine->Render( {visual} ); //note the curly braces!
With that you create a vector object out of the expression {visual} which then gets passed to the function.
1. very close in the sense that you just have to type one more character to make your code work. Instead of typying &, just type {, and one more } at the end. That is it. Life is so easy with C++11.
No, it isn't, which is rather fortunate because the behaviour of C arrays is abominable. If you find yourself looking for it, I would suggest instead looking for some new learning material w.r.t. C++.
The other answers are correct, but I'd like to add that it works the other way around:
void RenderingEngine::Render(Visual *visuals, size_t n_visuals);
Can be called like this:
vector<Visual> visuals;
m_renderingEngine->Render(&visuals[0], visuals.size());
You just take the address of the first element and pass it as if it was an array. This works because the elements of a vector are laid out sequentially in memory. (As pointed out in the comments, shouldn't use this in new code, of course. It's safer and easier to define you method to take a vector. However, if you already have a legacy function that takes a pointer, this allows you to use vectors in your own code.)
The reason it works this way around, but not the way in your question (pass a pointer, to a function that takes a vector), is that in your case it can't determine the size of the array at runtime. But it has to know the size to construct the vector:
// (wrong code)
// Passing one element:
Visual visual;
m_renderingEngine->Render(&visual);
// Passing two elements, how does Render know that
// there are two elements at that address?
Visual[2] visuals;
m_renderingEngine->Render(&visuals[0]);
As Nawaz pointed out, you can do something similar in C++11:
Visual visual;
m_renderingEngine->Render( {visual} ); // C++11
You can also put more elements in the {}. This only works because the compiler can tell at compile-time how many elements there will be. It's just syntactic sugar for:
vector<Visual> myVec = {visual}; // C++11
m_renderingEngine->Render(myVec);
which in turn works like the classic:
vector<Visual> myVec;
myVec.push_back(visual);
m_renderingEngine->Render(myVec);
(although the C++11 version might be slightly optimized, I don't know for sure).
Profiling of my application reveals that it is spending nearly 5% of CPU time in string allocation. In many, many places I am making C++ std::string objects from a 64MB char buffer. The thing is, the buffer never changes during the running of the program. My analysis of std::string(const char *buf,size_t buflen) calls is that that the string is being copied because the buffer might change after the string is made. That isn't the problem here. Is there a way around this problem?
EDIT: I am working with binary data, so I can't just pass around char *s. Besides, then I would have a substantial overhead from always scanning for the NULL, which the std::string avoids.
If the string isn't going to change and if its lifetime is guaranteed to be longer than you are going to use the string, then don't use std::string.
Instead, consider a simple C string wrapper, like the proposed string_ref<T>.
Binary data? Stop using std::string and use std::vector<char>. But that won't fix your issue of it being copied. From your description, if this huge 64MB buffer will never change, you truly shouldn't be using std::string or std::vector<char>, either one isn't a good idea. You really ought to be passing around a const char* pointer (const uint8_t* would be more descriptive of binary data but under the covers it's the same thing, neglecting sign issues). Pass around both the pointer and a size_t length of it, or pass the pointer with another 'end' pointer. If you don't like passing around separate discrete variables (a pointer and the buffer’s length), make a struct to describe the buffer & have everyone use those instead:
struct binbuf_desc {
uint8_t* addr;
size_t len;
binbuf_desc(addr,len) : addr(addr), len(len) {}
}
You can always refer to your 64MB buffer (or any other buffer of any size) by using binbuf_desc objects. Note that binbuf_desc objects don’t own the buffer (or a copy of it), they’re just a descriptor of it, so you can just pass those around everywhere without having to worry about binbuf_desc’s making unnecessary copies of the buffer.
There is no portable solution. If you tell us what toolchain you're using, someone might know a trick specific to your library implementation. But for the most part, the std::string destructor (and assignment operator) is going to free the string content, and you can't free a string literal. (It's not impossible to have exceptions to this, and in fact the small string optimization is a common case that skips deallocation, but these are implementation details.)
A better approach is to not use std::string when you don't need/want dynamic allocation. const char* still works just fine in modern C++.
Since C++17, std::string_view may be your way. It can be initialized both from a bare C string (with or without a length), or a std::string
There is no constraint that the data() method returns a zero-terminated string though.
If you need this "zero-terminated on request" behaviour, there are alternatives such as str_view from Adam Sawicki that looks satisfying (https://github.com/sawickiap/str_view)
Seems that using const char * instead of std::string is the best way to go for you. But you should also consider how you are using strings. It may be possible that there could be going on implicit conversion from char pointers to std::string objects. This could happen during function calls, for example.
I should preface this question by saying I think the answer is probably no, but I'd like to see what other people think about the issue.
I spend most of my time writing C++ that interacts with the Win32 API which like most C style APIs wants to either:
Take buffers which I've provided and operate on them.
Or return pointers to buffers which I need to later free.
Both of these scenarios essentially mean that if you want to use std::string in your code you've got to accept the fact that you're going to be doing a lot of string copying every time you construct a std::string from a temporary buffer.
What would be nice would be:
To be able to allow C style APIs to safely directly mutate a std::string and pre-reserve its allocation and set its size in advance (to mitigate scenario 1)
To be able to wrap a std::string around an existing char[] (to mitigate scenario 2)
Is there a nice way to do either of these, or should I just accept that there's an inherent cost in using std::string with old school APIs? It looks like scenario 1 would be particularly tricky because std::string has a short string optimisation whereby its buffer could either be on the stack or the heap depending on its size.
In C++11 you can simply pass a pointer to the first element of the string (&str[0]): its elements are guaranteed to be contiguous.
Previously, you can use .data() or .c_str() but the string is not mutable through these.
Otherwise, yes, you must perform a copy. But I wouldn't worry about this too much until profiling indicates that it's really an issue for you.
Well you could probably just const_cast the .data() of a string to char* and it would most likely work. As with all optimisations, make sure that it is actually this bit of the code that is the bottleneck. If it is, wrap this up in an inline-able function, or a template class or something so that you can write some tests for it and change the behaviour if it doesn't work on some platform.
I think the only thing that you can do safely with std::(w)string here is pass it as an input that's not going to be modified by its user; use .c_str() to get a pointer to (W)CHAR.
You may be able to use a std::vector<char> instead. You can directly pass a pointer to the first character into C code and let the C code write it which you can't do with a string. And many of the operations you'd want to perform on a string you can do on a std::vector<char> just as well.
Since C++11, you don't have to use temporary buffers. You can interchangeably use strings & c-strings and even write to the buffer of c++ strings, but you need to use string::front(), not string::data() or string::c_str() as those only return const char*. See Directly write into char* buffer of std::string.
I am concerned about buffer overflows, and I need to get some characters out of a class that derives from std::istream. From what I understand there is no way to stream to an std::string directly from an istream, without my own >> operator. So I was considering streaming the contents to a char array, then putting that into a std::string. Here is a simple example:
char CharArray[1000] = {0};
SomeIStream >> CharArray;
std::string StuffFromStream(CharArray);
However, there seems to be no way to know that CharArray will not be overflowed. Is there some maximum the stream extraction operator will write to chararray? Is there some way to check how much will be extracted preemptively? Is this just all wrong, Is there some way that is much better than this?
Edit1:, I fixed my not a memory leak. No need to call delete. I can't believe I did that.
Edit2: The suggestion to use the >> directly to string was suggested. I attempted that previous in the code base this problem came from and it failed. Saying that no suitable match for the operator could be found. I then tried with an std::fstream and it failed again. Trying the std::fstream code in simple minimalistic project succeeded. This tells me that something else is wrong with my larger project. The original intent of this question is no longer valid.
Edit3: I solved this. I was attempted to stream to a typedef String, which I thought was actually and std::string, but it was really a const std::String. Naturally there isn't a stream extraction operator for writing to an unwritable object, so it just gave me all the operators listed in the istream header (the one I needed was in the string header).
Thanks to the people who pointed out my faulty research and pointe me in the right direction.
If you've (properly) inherited from std::istream, then you don't need to do anything special and can just use operator >> (std::istream&, std::string&).
std::string s;
SomeIStream >> s;
When I say "properly," I mean overridden the appropriate virtual functions from istream.
"I know that if there is an exception before the delete this will leak memory." No it won't. You didn't allocate CharArray with new; calling delete on it will not do what you want.
If you want to read the whole stream into a string, this is not terribly efficient, but is safe:
std::string str((std::istream_iterator<char>(some_istream)), std::istream_iterator<char>());
(note the extra parenthesis, to avoid the most-vexing-parse)
If you want to read up to "n" characters:
some_istream.read(some_char_array, sizeof(some_char_array));
note that this won't null-terminate the array. Pass sizeof(char_array) - 1 instead if you want to leave the array's last char untouched.
All streams offer the .str() method, which will provide a copy of their buffer as a std::string (or wstring or whatever for other typedefs).
Also, you declared an array on the stack and then tried to delete it, which is UB.
Mixing old-school C-style char arrays with streams? Seems like some very confused code.
Commentary aside, just extract directly to a string. You can pass that (via the c_str() method) to C-style APIs that expect const char* parameters. And if for some bizarre reason you really do nead a char array, you can copy from the string to the char array safely, after checking bounds.
By the way, you've pretty clearly illustrated the main way in which magic numbers are evil. In your case, the magic number in question is 1000. You have no idea that 1000 is appropriate -- not too big, not too small -- without totally guessing. In programming, guessing often == crashing. Or even worse, not crashing.
By the way 2, you are deleteing an automatic variable above. You don't do this. Use delete if and only if you use new. You didn't new, so don't delete.
By the way 3, if you just want to extract the whole stream in to a string, you can just do this:
string s = SomeIStream.str();
This is what my approach usually is (from "Thinking in C++" by Bruce Eckel)::
ifstream in("somefile.txt",ios::in);
istreambuf_iterator istr(in),end;
string str;
insert_iterator ins(str,str.begin());
while(istr != end){
*ins++ = *istr++;
}
In the above code the whole file is taken as a character stream and then put into a string. This is shown just as an example.
We are using the CString class throughout most of our code. However sometimes we need to convert to a char *. at the moment we have been doing this using variable.GetBuffer(0) and this seems to work ( this mainly happens when passing the Csting into a function where the function requires a char *). The function accepts this and we keep going.
However we have lately become worried about how this works, and whether there is a better way to do it.
The way i understand it to work is it passes a char pointer into the function that points at the first character in the CString and all works well.
I Guess we are just worried about memory leaks or any unforseen circumstances where this might not be a good idea.
If your functions only require reading the string and not modifying it, change them to accept const char * instead of char *. The CString will automatically convert for you, this is how most of the MFC functions work and it's really handy. (Actually MFC uses LPCTSTR, which is a synonym for const TCHAR * - works for both MBC and Unicode builds).
If you need to modify the string, GetBuffer(0) is very dangerous - it won't necessarily allocate enough memory for the resulting string, and you could get some buffer overrun errors.
As has been mentioned by others, you need to use ReleaseBuffer after GetBuffer. You don't need to do that for the conversion to const char *.
# the OP:
>>> I Guess we are just worried about memory leaks or any ...
Hi, calling the GetBuffer method won't lead to any memory leaks. Because the destructor is going to deallocate the buffer anyway. However, others have already warned you about the potential issues with calling this method.
#Can >>> when you call the getbuffer function it allocates memory for you.
This statement is not completely true. GetBuffer(0) does NOT allocate any memory. It merely returns a pointer to the internal string buffer that can be used to manipulate the string directly from "outside" the CString class.
However, if you pass a number, say N to it like GetBuffer(N), and if N is larger than the current length of the buffer, then the function ensures that the returned buffer is at least as large as N by allocating more memory.
Cheers,
Rajesh.
MVP, Visual ++.
when you call the getbuffer function it allocates memory for you.
when you have done with it, you need to call releasebuffer to deallocate it
try the documentation at http://msdn.microsoft.com/en-us/library/awkwbzyc.aspx for help on that.