Jump to content

C-style strings vs library strings

RexLee

The book(C++ Primer 5th edition) I'm reading says C-style strings should not be used by c++ programs  because they are the root to many security problems.Why?And how are the two different?And in what case should I use C-style strings or never use?

Link to comment
Share on other sites

Link to post
Share on other sites

I will also ask is it really better to use vectors and iterators instead of pointers and arrays?And which ones are more frequently used in real world applications?

Link to comment
Share on other sites

Link to post
Share on other sites

With C-style strings it's far more common to attempt to read from memory that has not been initialised as part of the array (for example, having requested an array of size 10 and requesting the 10th element, actually being the 11th) where as using the library data structures you have more restriction on your uses with predefined methods that allow you to interact with them. By using strings you are presented with the functionality that is applicable and will receive an error if this is not deemed possible, something you won't necessarily get with C-strings.

Link to comment
Share on other sites

Link to post
Share on other sites

With C-style strings, you need to reallocate when changing the string. There's a more direct handling of the string. An std::string has operators for all of this already. You could make your own string class however. "rexlee_string" or something. However, that would require a lot of work from your side in optimising it. It also sounds like you're new to C++/programming, so that would be highly unrecommendable.

Here's an example:

char* mycstring = "My C-string";char* yourcstring = "Your C-string";std::cout << mycstring + yourcstring;

Now, that creates a problem because mycstring and yourcstring are POINTERS. And also, it's an array, and the c-string is the pointer to the first index.
If you allocated more memory for your c-string and don't delete it before it goes out of scope, you've got yourself a memory leak.
It's much easier with std::string, as you can use the operators as with a number. (well, not - * and / etc) and it deals with all the dynamic stuff itself.

There comes a point where you need to use char arrays though. A buffer for instance. Maybe for networking or filereading/writing.
(Though, there's a C++ alternative for this too, called std::stringstream, you should look it up - it's very useful sometimes)

As for your second question, it depends.
If you want an array that only needs, let's say 10 elements, then you should go for a static array. "int myarray [10];"
However, if you're not sure how many elements you need, you should go for an std::vector.
When you're using polymorphism or have another need for pointers in the vector, use the new operator and pointers as the vector type. If you don't need a pointer, just make it an std::vector<int>, for example.

I am not a fan of iterators however. I have never ever used them to be honest. They do have a use, but it's really rare and you usually don't have to use them.
A typical loop to iterate over all elements in a vector should look like this:

unsigned int vectorsize = myvector.size();for (unsigned int i = 0; i < vectorsize; i++) {    std::cout << myvector[i];}

Well, honestly I never assign the size to a variable, but it's faster in some cases.

So yeah. static arrays should be normal arrays, but vectors are very good for dynamic arrays. Just the same way C++ strings are good for dynamic strings. :)

It makes everything less tedious.

Hope I was at help.

~dib

Link to comment
Share on other sites

Link to post
Share on other sites

I get it now.But what is a memory leak?And what will cause memory leaks?

Link to comment
Share on other sites

Link to post
Share on other sites

When you call the "new" operator, you allocate memory dynamically. Which means you can create a dynamic array.
You can't do
int maxnumbers = 10;int mynumbers [maxnumbers];
 
because maxnumbers can be a random number. And that random number would be different every time you started the program.
Therefore the compiler can't deal with that. So you have to use the "new" operator.
 
Like this:
int maxnumbers = 10;int mynumbers = new int [maxnumbers];
The "new" operator is a function that allocates the memory for you.
 

However, it doesn't "delete" itself automatically. If you don't delete it yourself, the program will not free the memory you allocated.

Therefore, if you call "new" a lot and don't "delete" it afterwards, the program will use more and more memory and then suddenly you don't have more free memory.

If you see your little program using hundreds of megabytes, and it increases by 5 or 10 megabytes every second - you might have got yourself a continuous memory leak. (not a real term I think)

 

So the solution is to delete mynumbers when you're done with it. If you don't do that, the memory will be lost until you close the program. In some rare cases, the computer.

If you are going to use the mynumbers variable later on, then you should set it to NULL  (which is 0) so you can check if it has a valid memory address or not. Because when you delete the array, the array is completely gone.

 

Also, this is valid C++ code:

int* mynumbers = new int [10];delete mynumbers;mynumbers = NULL;delete mynumbers;

You see, "delete" checks if the pointer is NULL (or 0) before it tries to actually delete it.

So you don't need to do stuff like

if (mynumbers) { // or mynumbers != NULL - both works, as if mynumbers equals zero, then it's already false. As "false" is synonumous with "0"    delete mynumbers;}

Hope I helped.

 

~dib

Link to comment
Share on other sites

Link to post
Share on other sites

Thanks for the explanation.I get it now.By the way how do you guys know so much?

Link to comment
Share on other sites

Link to post
Share on other sites

Most tutorials won't teach you more than what's on the surface. Keep that in mind.

There's a lot of stuff going in functions. "new" is a function for example. It's not a "magic" thing.

By the way, when you understand classes, functions, polymorphism and pointers. You're ready to make graphical programs. You'll figure it out when the time is right. That's how it happened with me at least.

What I did, if you care:

I started with GameMaker in April 2008 and used it every now and then for fun.

Then I decided I wanted to do "the real thing", being dependence phobic (still kind of am to be honest...) and I started with C# (yeah, dependencephobia amirite-.-) in ~2010 (I made Tic Tac Toe and went back to GM lol :rolleyes:)

After a while I went to C++ since that was kewlnstuf and failed horribly, only being able to make some stupid stuff and looking at my code from then, I'm honestly embarrassed. :mellow:

I then went back to GM again, and I actually made a pretty cool thing as a last project before I actually successfully got into C++ in mid-June 2011.

So yeah, it's been weird.

Link to comment
Share on other sites

Link to post
Share on other sites

Interesting.I hope I can also get good at c++ one day.

Link to comment
Share on other sites

Link to post
Share on other sites

By the way (this is kinda off topic).I don't really get this code.

#include <iostream>int main(){    int arr[3][4];    for(int i = 0; i < 3; i++)    {            for(int j = 0; j < 4; j++)            {                    arr[i][j] = i * j;            }    }    for(int (*p)[4] = arr; p != arr + 3; ++p)         //this part    {            for(int *q = *p; q != *p + 4; ++q)            {                    std::cout << *q << ",";            }    }                                                //to here    system("PAUSE");    return 0;}

Thanks for the help before.

Link to comment
Share on other sites

Link to post
Share on other sites

Thanks a lot for posting that question. I have to admit I had no idea what was going on myself at first.

I had never seen the int (*p)[x] declaration before.

I've used around 20-30 minutes now commenting it and trying to understand.

It was very confusing. Hehe.

Here is my explanation. Now, I do want to add a DISCLAIMER. I am not sure if what I'm saying is 100% correct, but it all makes sense to me at least..

http://pastebin.com/SFv0Swz6

Here is a link, because the forum messed up the formatting.

It seriously got all in one line and idk what happened lol.

~dib

Link to comment
Share on other sites

Link to post
Share on other sites

I forgot to say: Good luck on your programming journey! :)

 

I know that you maybe won't understand the explanation, but don't feel bad if you don't do. I had a hard time commenting it.

Thanks again for posting the question that helped improve me as a programmer. :)

 

~dib

Link to comment
Share on other sites

Link to post
Share on other sites

Thank you for commenting the whole thing so that I would get it.I also looked in the book for helpful information.And I found this: If we supply fewer fewer subscripts than there are dimensions, then the result is the inner-array element at the specified index.

//assigns the first element of arr to the last element in the last row of iaia[2][3] = arr[0][0][0];int (&row)[4] = ia[1]; // binds row to the second four-element array in ia
Link to comment
Share on other sites

Link to post
Share on other sites

I have a question that is string related.

while(std::cin >> curr_read)

(curr_read is a string)

The problem is it won't stop trying to get the input even if I press enter.Is there something that I can type to make it know that it has reached end of input?

Link to comment
Share on other sites

Link to post
Share on other sites

That's because the >> operator returns a non-zero value (which is maybe a bool, I don't know).

So every time it's successful at setting "curr_read" to what you typed, it will keep going. An empty input doesn't mean it will fail (or return zero at all for that matter).

 

What you probably need to do is this:

while (curr_read != "") { // If the curr_read string is not empty    std::cin >> curr_read; // Request another input}

The code is redundant, but I don't know what you're doing, so. Lol.

 

~dib

Link to comment
Share on other sites

Link to post
Share on other sites

I tried it, but for some reason it still doesn't work.

I'm trying too write a program to see all the inputs and see which word repeats (must be repeated immediately) the most time and output which word and times. 

#include <iostream>#include <string>#include <vector>int main(){    std::vector<std::string> input;    std::string curr_read;    int curr_cnt = 0;    int last_cnt = 0;    std::string curr_word;    std::string last_word;    while(std::cin >> curr_read)    {                   input.push_back(curr_read);    }    std::vector<std::string>::const_iterator beg = input.begin();    std::vector<std::string>::const_iterator end = input.end();    while(beg != end)    {              if(beg == (++beg))              {                     curr_word = (*beg);                     ++curr_cnt;                     ++beg;              }              if(beg != (++beg))              {                     if(curr_cnt >= last_cnt)                     {                                 last_cnt = curr_cnt;                                 curr_cnt = 0;                                 last_word = curr_word;                                 curr_word = " ";                                 ++beg;                                 std::cout << last_word << last_cnt;                     }                     if(curr_cnt < last_cnt)                     {                                 curr_cnt = 0;                                 curr_word = " ";                                 ++beg;                                 std::cout << last_word << last_cnt;                     }              }    }    std::cout << "The word that repeated most times is: " << last_word << std::endl;    std::cout << "Number of times: " << last_cnt << std::endl;    system("PAUSE");    return 0;}

I haven't tested the rest of it yet so I'm not sure if the last parts work.

ex. input: how now now now brown cow cow

      output: The word that repeated most times is: now

                 Number of times: 3

Link to comment
Share on other sites

Link to post
Share on other sites

I suppose this is what you wanted:

I put a dot as the delimiter for asking for new words as I'm not good with console stuff, and therefore don't know how to input blank.

I don't know if it's possible using the >>operator.

 

What I changed:

I did not use iterators, as they aren't necessary here. They just make everything more complicated than it needs to be.

I also removed some redundant if-conditions, because it's the opposite of the first one, therefore you don't need to check if it's the opposite. Because it already is.  :huh:

 

By the way, the reason you can't do while (std::cin >> mystring) is because the >>operator returns std::cin. That's why you can do std::cin >> test >> test2 >> test3 and same with std::cout.

I did not realise it as I wrote the last post.

 


Anyway. I hope this helps.

You should be able to understand the code without comments.

 

~dib

 

EDIT: GODDAMN IT the code tag is so fucking buggy. I'll post it to Pastebin instead.

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×