0

I'm trying to create a program that stores words of a string within the space in an array(For example: If user inputs - "Hello what's up" ,So i want to store Hello, What's,Up in an array of thier respective indices (Hello in 0th index,What's in 1st index and up in 2nd index). I'm using c method of DMA in c++ to achieve this. Following is my code- https://code.sololearn.com/cNWxZV9IoG4q/?ref=app

#include <iostream>
#include <sstream>
#include <cstdlib>
using namespace std;

int main() {
    string sentence;
    getline(cin,sentence);
    stringstream ss(sentence);
    string *words;
    int count=0;
    
    while(ss>>sentence)
    {
     if(count==0)
     {        
   words=
  (string*)malloc((count+1)*sizeof(string));
  *(words+count)=ss.str();
  count++;
  continue;
     }
      words=(string*)realloc(words, (count+1)*sizeof(string));
    *(words+count)=ss.str();
    free(words);
      count++;
    }
    
    return 0;
}

But , I'm getting error , Could anyone please fix it?

Jason
  • 36,170
  • 5
  • 26
  • 60
Manav Roy
  • 33
  • 6
  • Post the code here in your question so that in case the site you linked to breaks, future readers will still be able to see it. Moreover, having code here would make this question more concise. – Jason May 28 '22 at 09:45
  • Why is this tagged "C++" when you are clearly writing "C"? – Jesper Juhl May 28 '22 at 09:52
  • @JesperJuhl It's c++ , I'm just using c style of dynamic memory allocation in c++. – Manav Roy May 28 '22 at 09:54
  • 3
    "I'm just using c style of dynamic memory allocation in c++." That's exactly your problem. `words=(string*)malloc((count+1)*sizeof(string));` You can't do that. C++ is not C. You can't `malloc` a non-trivial C++ class. Please learn how to use `std::vector`. – n. m. could be an AI May 28 '22 at 09:54
  • 3
    Avoid C style constructs in C++ whenever there's a choice. – kotatsuyaki May 28 '22 at 09:55
  • @n.1.8e9-where's-my-sharem.As far as i know,We can use malloc,calloc,realloc in c++ – Manav Roy May 28 '22 at 09:56
  • 1
    C++ objects (such as `std::string`) have constructors. Don't use `malloc` in C++ code. – heap underrun May 28 '22 at 09:57
  • @kotatsuyaki As we do not have realloc in c++ style of dynamic memory allocation, That's why I'm using c style of dma. – Manav Roy May 28 '22 at 09:58
  • @heapunderrun Sorry but can you please explain this again?? – Manav Roy May 28 '22 at 09:59
  • 1
    Sure, you *can* use `malloc` in C++, but it doesn't run the constructor of `std::string` for you, which means that the `std::string` objects are not properly initialized in your code. – kotatsuyaki May 28 '22 at 10:00
  • 1
    @ManavRoy You *can* use C-style allocation in C++ but there’s never a good reason to, *especially* when you don’t know how to use it correctly. — You don’t need `realloc` in C++ if you use C++ properly (e.g. by using vectors or, for low-level code, allocators). And in particular you *can’t* use `realloc` with non-trivial types. It doesn’t work. – Konrad Rudolph May 28 '22 at 10:00
  • @kotatsuyaki Sorry for disturbing you , But I'm not getting the term "string object's" ,I think that string is a datatype and not class ,So what does it has to do with objects? – Manav Roy May 28 '22 at 10:03
  • 1
    The `string` in your code refers to `std::string` defined in `` header of the C++ STL. It is not a primitive type but actually a class. – kotatsuyaki May 28 '22 at 10:04
  • You are not the first person to try to `realloc` an array of C++ objects "for efficiency", and most certainly not the last one. People coming to C++ from C were trying to do this since C++ was invented. It didn't work back then, and it doesn't work now. – n. m. could be an AI May 28 '22 at 10:08
  • 3
    The memory representation of an `std::string` object typically consists just of some pointers into dynamically allocated memory that `std::string` object manages itself. The class has member functions / operators to assign strings etc., it allocates and manages its internal buffer itself. When you just `malloc` and brutally write at the allocated memory region, you are clobbering `std::string`'s internal pointers (which, by the way, are not even initialized at that point, because the constructor didn't run). This is not the way how C++ is meant to be done. – heap underrun May 28 '22 at 10:10
  • I've saw you guys are using the term "constructor of string object" I've a question,Is string a class or object? And what do you mean by string constructor? What's present in string constructor? – Manav Roy May 28 '22 at 10:25
  • `std::string` is a class (i.e. the type). The class is used to create objects of the type `std::string`. I suggest you to go through some materials on this topic if you want to know more about classes and objects in C++. – kotatsuyaki May 28 '22 at 10:30
  • @kotatsuyaki So ,std::string is a class ,And string variable (string str[str in this case]) is a object of string class? – Manav Roy May 28 '22 at 14:35
  • Yes, you are correct. – kotatsuyaki May 28 '22 at 14:37

1 Answers1

4

Don't use C in C++. Just use a std::vector to store the words:

std::string word;
std::vector<std::string> words;

while (ss >> word) {
    words.push_back(word);
}

And then you can print the individual words like so:

for (auto& word: words) {
    std::cout << word << '\n';
}

Or if you wish to use indices:

for (std::size_t i = 0; i  < words.size(); ++i) {
    std::cout << i << ": " << words[i] << '\n';
}

The reason why your code fails is, as @heapunderrun mentioned, the fact that std::string has a constructor. If you don't call the constructor in some way, then the string will be in an indeterminate state. When you try to assign to such a string, like in:

*(words+count)=ss.str();

Then your program will crash. If you really want to use manual memory allocation, then you have to use new and delete. You can use malloc() if you really want to, but then you still should use placement new to ensure the std::string objects are correctly constructed inside the memory you allocated. Finally, you probably can't use realloc() safely, you would have to malloc() a new array, copy everything properly to the new array, then free() the old array.

G. Sliepen
  • 7,637
  • 1
  • 15
  • 31
  • I don't wanna use STL ,I wanna use c style of dma here. – Manav Roy May 28 '22 at 09:59
  • 2
    @ManavRoy "I don't wanna use STL ,I wanna use c style of dma here." - Why??? – Jesper Juhl May 28 '22 at 10:01
  • @JesperJuhl I've not study STL yet ,Plus I'm weak in DMA , That's why. – Manav Roy May 28 '22 at 10:04
  • 2
    @ManavRoy The issue is that manual memory management in C++ is just a bad idea, you will learn bad coding habits this way. Stick to the STL. If you want to learn manual memory management, I suggest you write some program in pure C. – G. Sliepen May 28 '22 at 10:06
  • 7
    As a side note, the term *DMA* usually refers to *direct memory access*, which has nothing to do with heap memory allocation. – kotatsuyaki May 28 '22 at 10:07