Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read in data of a dynamic size into char*?

Tags:

c++

char

I was wondering how the following code works.

#include <iostream>
using namespace std;
int main()
{
    char* buffer = new char(NULL);
    while(true)
    {
        cin >> buffer;
        cout << buffer;
        cout << endl;
    }
    return 0;
}

I can input any amount of text of any size and it will print it back out to me. How does this work? Is it dynamically allocating space for me?

Also, if I enter in a space, it will print the next section of text on a new line. This however, is fixed by using gets(buffer); (unsafe).

Also, is this code 'legal'?

like image 322
Rhexis Avatar asked Feb 21 '23 07:02

Rhexis


2 Answers

It's not safe at all. It's rewriting whatever memory happens to lie after the buffer, and then reading it. The fact that this is working is coincidental. This is because your cin/cout operations don't say "oh, a pointer to one char, I should just write one char" but "oh, you have enough space allocated for me."

Improvement #1:

char* buffer = new char(10000) or simply char buffer[10000];

Now you can safely write long-ish paragraphs with no issue.

Improvement #2:

std::string buffer;

To answer your question in the comment, C++ is all for letting you make big memory mistakes. As noted in comment this is because it's a "don't pay for what you don't need" language. There are some people who really need this level of optimization in their code although you are probably not one of them.

However, it also gives you plenty of ways to do it where you don't have to think about memory at all. I will say firmly: if you are using new and delete or char[] and not because you are using a design pattern with which you've familiarized that require them, or because you are using 3rd-party or C libraries that require them, there is a safer way to do it.

Some guidelines that will save you 80% of the time:

-Don't use char[]. Use string.

-Don't use pointers to pass or return argument. Pass by reference, return by value.

-Don't use arrays (e.g. int[]). Use vectors. You still have to check your own bounds.

With just those three you'll be writing "pretty safe", non-C-like code.

like image 154
djechlin Avatar answered Mar 03 '23 10:03

djechlin


This is what std::string is for:

std::string s;

while (true)
{
    std::cin >> s;
    std::cout << s << std::endl;
}

std::string WILL dynamically allocate space for you, so you don't have to worry about overwriting memory elsewhere.

like image 25
Richard J. Ross III Avatar answered Mar 03 '23 11:03

Richard J. Ross III