#include <iostream>
#include <string>
#include <fstream>
using namespace std ;
int main() {
char *file_name = "doc.txt" ;
ifstream fin ;
fin.open( file_name ) ;
if( ! fin ) {
cout << "Problems opening " << file_name << endl ;
return -1 ;
}
const unsigned MAX = 100 ;
string doc[MAX] ;
unsigned word_count = 0 ;
//while( fin >> doc[ word_count++ ] ) ;
while( fin >> doc[ word_count ] ) {
cout << doc[ word_count ] << endl ;
word_count ++ ;
}
fin.close() ;
return 0 ;
}
27 Replies - 2161 Views - Last Post: 26 February 2012 - 04:21 AM
#1
allocating to heap
Posted 22 February 2012 - 08:06 PM
Replies To: allocating to heap
#2
Re: allocating to heap
Posted 22 February 2012 - 08:10 PM
#include <sstream> ... std::stringstream sstr; sstr << file.rdbuf(); std::string contents = sstr.str();
This post has been edited by Karel-Lodewijk: 22 February 2012 - 08:11 PM
#3
Re: allocating to heap
Posted 22 February 2012 - 08:18 PM
#4
Re: allocating to heap
Posted 22 February 2012 - 08:28 PM
fin.seekg (0, std::ios::end); //puts file pointer at the end size_t length = fin.tellg(); //gives position fin.seekg (0, std::std::beg); //important, put file pointer back
Then you can allocate a buffer of the appropriate size.
char* buffer = new char[length];
And then you would fill the buffer.
fin.read(buffer, length);
There are no doubt other ways to go about it, but this will work and won't waste space.
This post has been edited by Karel-Lodewijk: 22 February 2012 - 08:32 PM
#5
Re: allocating to heap
Posted 22 February 2012 - 08:33 PM
#6
Re: allocating to heap
Posted 22 February 2012 - 09:02 PM
Well you would start by initializing a buffer of a certain size. Then you would read that amount of bytes or until eof(end of file). If you don't reach the end of file, you would allocate a new buffer that is larger, typically you would multiply the size by some multiplier > 1 because it gives a lower asymptotic complexity. Copy everything you've read and continue reading from the file.
If you don't mind using some C functions. Allocating with malloc will allow you to do the allocation of the new buffer with realloc. Realloc has the advantage that it will try to grow the buffer if there is trailing space and it will do the copying for you if there is not.
something like:
size_t size = 10;
size_t old_size = 0;
char* buffer = new char[size];
size_t read = 0;
while (true) {
read += fin.read(buffer + old_size, size-read);
if (fin.eof()) break;
char* old_buffer = buffer;
old_size = size;
size *= 2;
buffer = new char[size];
std::copy(old_buffer, old_buffer+old_size, buffer);
delete[] old_buffer;
}
or more c-style
size_t size = 10;
size_t old_size = 0;
char* buffer = (char*)malloc(size);
size_t read = 0;
while (true) {
read += fin.read(buffer + old_size, size-read);
if (fin.eof()) break;
old_size = size;
size *= 2;
buffer = realloc(buffer, size);
}
Not tested, proceed with caution, I would much prefer the first 2 methods
Edit: Already found a mistake, you should offcourse start writing further into the buffer (buffer+old_size).
This post has been edited by Karel-Lodewijk: 22 February 2012 - 09:15 PM
#7
Re: allocating to heap
Posted 22 February 2012 - 09:17 PM
char *buffer = new char[MAX] ;
This post has been edited by mando414: 22 February 2012 - 09:19 PM
#8
Re: allocating to heap
Posted 22 February 2012 - 09:21 PM
mando414, on 23 February 2012 - 04:17 AM, said:
double *dvalues = new double[MAX] ;
If you want to use realloc, no, the C and C++ heap functions do not mix. Either you use malloc/realloc/calloc and free or you use new/new[] and delete/delete[].
Also mind that the parameter of malloc is the size in bytes, so if you use it for doubles, use:
double *dvalues = (double*) malloc (MAX*sizeof(double));
This post has been edited by Karel-Lodewijk: 22 February 2012 - 09:21 PM
#9
Re: allocating to heap
Posted 22 February 2012 - 09:24 PM
yea sorry i pasted from old code, the file im reading in shouldnt contain any doubles
This post has been edited by mando414: 22 February 2012 - 09:26 PM
#10
Re: allocating to heap
Posted 22 February 2012 - 09:30 PM
#11
Re: allocating to heap
Posted 22 February 2012 - 09:30 PM
It's more complicated and less efficient, that's why I suggested the realloc in the first place.
I've always wondered why C++ doesn't have a standard function to resize 'new' allocated memory. They could have called it renew. I guess constructors got in the way.
This post has been edited by Karel-Lodewijk: 22 February 2012 - 09:37 PM
#12
Re: allocating to heap
Posted 22 February 2012 - 10:55 PM
#include <iostream>
using namespace std ;
struct raw_node
{
int x ;
struct raw_node* next ;
} ;
typedef struct raw_node node ;
int main()
{
node *head, *current ;
head = new node() ;
head->next = 0 ;
current = head ;
cout << "Enter your list of positive ints. End with a negative or zero." << endl << endl ;
int temp ;
do
{
cout << "Next: " ;
cin >> temp ;
current->x = temp ;
current->next = new node() ;
current = current-> next ;
current->next = 0 ;
}
while( temp > 0 ) ;
current = head ;
do
{
temp = current->x ;
cout << temp << endl ;
current = current->next ;
}
while( current->next != 0 ) ;
return 0 ;
}
#13
Re: allocating to heap
Posted 24 February 2012 - 02:42 PM
Karel-Lodewijk, on 23 February 2012 - 05:30 AM, said:
#14
Re: allocating to heap
Posted 24 February 2012 - 03:02 PM
Quote
I've actually never understood why C++ made operators for allocation; to me it seems to be something that should always be handled by a class or set of functions. std::allocator could have had a realloc but it didn't work out that way
think about it, how do you make an OS in C++ if C++ requires dynamic memory allocation as a fundamental? that part always has to be done in C or assembly.
also, I don't think constructors would be an issue. if the the old data is getting deleted only to copy the new data you can just do a binary copy. smart pointers wouldn'and file handles wouldn't be affected even. You would have to define it in the standard so that it didn't call any constructors or destructors though.
This post has been edited by ishkabible: 24 February 2012 - 03:05 PM
#15
Re: allocating to heap
Posted 24 February 2012 - 05:12 PM
ishkabible, on 24 February 2012 - 10:02 PM, said:
Quote
I've actually never understood why C++ made operators for allocation; to me it seems to be something that should always be handled by a class or set of functions. std::allocator could have had a realloc but it didn't work out that way
think about it, how do you make an OS in C++ if C++ requires dynamic memory allocation as a fundamental? that part always has to be done in C or assembly.
also, I don't think constructors would be an issue. if the the old data is getting deleted only to copy the new data you can just do a binary copy. smart pointers wouldn'and file handles wouldn't be affected even. You would have to define it in the standard so that it didn't call any constructors or destructors though.
Well for all practical purposes new and delete are functions. I can perfectly write you a new<Type>(constructor_params) function that acts as a new and passed the given parameters directly to the constructor, and accompanying delete2 function. In c++11 I can anyhow.
The major difference between C's memory allocation function and C++'s memory allocation function is basically that the C functions only allocate memory, they do not initialize they dot interpret what type it is, you ask for x bytes and get x bytes. C++'s new does 2 things, it allocates memory, just as C does, but after that it types the memory and starts initializing the data. i.e.: running constructors or in case of built-in types initializing with given value if provided. Therefor a renew/realloc would call for a bunch of new constructors to run or if you make it smaller a bunch of destructors. And if you have to copy the memory because of a realloc, do you run a bunch of copy constructors and destructors afterwards, in some use case you might have to for something to work properly, in some use cases it will break ?
You say, just doing a binary copy is often not that straightforward objects might have pointers or references pointing to things within the object itself or there might be external pointers/references pointing to something within an object, these pointers/references will all be invalid afterwards. Similar to how relocations within an stl container invalidates iterators. Keeping track of these things can be done but at quite a bit of hidden cost. C's realloc also has a similar problem but C has no references and it simply states that realloc invalidates internal pointers.
std::allocater actually works different than new/delete. It is created in part because for high-performance dynamic containers new and delete is not very efficient. For example When you create a vector, you want to allocate a large enough block of memory so your container can grow, but you really can't use new for this because you don't want to run a bunch of constructors for objects that do not exist. It might not even be possible, the type might not have a default constructor at all. So std::allocator has 3 function allocate/construct/destroy, which brings us back to the C world really where allocating memory and interpreting/initializing/constructing are 2 separate things. You could do something similar with a placement new when initializing and placing those objects in larger blocks of memory allocated by C's memory function. std::allocater might very well be implemented this way.
About the OS part, you can write an OS in C++, initially you cannot use virtual memory, C++ does not require it as a fundamental, only the stl does. But the way an OS or rather a kernel handles memory is different than how a user process does. One of the first thing a kernel does is run some bios(the kernel's os
Anyway I've strayed way off topic here.
This post has been edited by Karel-Lodewijk: 24 February 2012 - 05:28 PM
|
|

New Topic/Question
Reply




MultiQuote







|