Thread: Using peek to make a dynamic array

  1. #1
    Registered User
    Join Date
    Sep 2009
    Posts
    29

    Using peek to make a dynamic array

    Hi all!

    I'm trying to read a string of characters from a file (terminating at the first space, newline, or tab character), dynamically allocate memory for it, and then copy the contents of the file to the allocated memory.

    I keep getting weird output from the following code. For some reason, it allocates the memory for the array fine, but it reports the array size as 4. It only outputs part of the array (first 4 characters), and then when it goes to deallocate the memory, it gives me a heap corruption error! :P I've also reproduced the file's contents at the end of this (really small). Can anyone help figure out what's going wrong here?

    Please note the int flag is no longer really used. I used him for debugging earlier.

    Thanks!!

    -Max

    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    
    using namespace std;
    
    int main()
    {
    	
    	char c =0;
    	char *chararray = NULL;
    	
    	int flag = 0; 
    	int count = 0;
    	
    	ifstream myin("mytest.txt");
    	if (myin.bad())
    		cout << "Bad file!!";
    
    	while (c != '\t' && c != '\n' && c!= ' ')
    	{
    		c = myin.peek();
    		cout << c;
    		++count;
    		myin.seekg(count, ios::beg);
    		flag = myin.tellg();
    	}
    	chararray = new char[count];
    	int sizeofarray = sizeof(chararray);
    	cout << endl << endl << sizeofarray <<  endl  << sizeof(char) << endl;
    	myin.seekg(0, ios::beg);
    	myin.read(chararray, count);
    	chararray[count] = '\0';
    	for (int a=0; a < sizeofarray; a++)
    		cout << chararray[a];
    	cout << endl <<  count << endl;
    	delete chararray;
    }
    File mytest.txt:
    Readmeyoubiotch!! 3.46 34534sdf

  2. #2
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    chararray is declared as a char pointer, so naturally it's size will always be four bytes on a 32 bit machine.

    Just use count as the size of the array. It's guaranteed to work.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  3. #3
    Registered User
    Join Date
    Sep 2009
    Posts
    29
    I wouldn't have been able to simply set count as the size of the array, since this has to be done dynamically.

    I figured out the gibberish. I was writing to the end of the array. As such, there was no termination character '\0'. So, what I was seeing was all of the bordering data/garbage.

    As far as throwing the error whenever it went to delete, it was because I was writing past the array bounds. In case anyone reads this, I've posted the updated code below

    Thanks for the help!

    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    
    using namespace std;
    
    int main()
    {
    
    	char c =0;
    	char *chararray;
    	
    	int flag = 0; 
    	int count = 0;
    	
    	ifstream myin("mytest.txt");
    	if (myin.bad())
    		cout << "Bad file!!";
    
    	while (c != '\t' && c != '\n' && c!= ' ')
    	{
    		c = myin.peek();
    		cout << c;
    		++count;
    		myin.seekg(count, ios::beg);
    		flag = myin.tellg();
    	}
    	chararray = new char[count + 1];
    	int sizeofarray = sizeof(chararray);
    	cout << endl << endl << sizeofarray <<  endl  << sizeof(char) << endl;
    	myin.seekg(0, ios::beg);
    	myin.read(chararray, count);
    	chararray[count] = '\0';
    	cout << chararray;
    	cout << endl <<  count << endl;
    	delete [] chararray;
    
    }

  4. #4
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    why not to use string?
    if you need to work with it as a buffer - why not to use vector of chars?

    What will happen to your code if file contains 1 line that does not contain any white chars? and does not contain \n?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  5. #5
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    you cannot use sizeof() to determine the size of a dynamically allocated array. sizeof will only give you the size of the pointer itself, not what it points to. you need to keep track of it yourself, and the count variable is the perfect way to do it. if allocation succeeds (new returns a valid, non-NULL pointer), then count contains the number of bytes that you know you can read into the buffer. it seems that you are trying to duplicate the functionality of the >> operator from std::istream. why not just use >> and an std::string? it would eliminate about 75% of your code.

    on a side note, you should always return 0 from main() unless there is a problem, in which case you can return a different number to indicate what the problem was.

  6. #6
    Registered User
    Join Date
    Sep 2009
    Posts
    29
    I would love to use string! In fact, if you guys know a way of it, I'm all ears. The problem I have is that you can't use an extraction operator of a file with a string.

    Ex:
    Code:
    ifstream myFile("somefile.txt");
    string myString = "";
    myFile >> myString;
    If I do the above, the compiler craps out on me.

    This isn't the entirety of what I'm attempting to do (which is why I didn't return a value for main-- don't care at this point!

    Here is the chief issue: I have a file. It has either names of soda pop (which may have spaces in the name, ex: "Coca Cola"), prices for the soda in (ex 2.45), and a number of cases of the soda sold (integers). So, I need to read a string, determine if it's actually a number, and then handle accordingly.

    Originally I wanted to handle the code as above... However, when the compiler told me it hates that idea, I was forced to think about it as a dynamic string (since I have no idea of the length or number of the names)... This code is the first step in reading one name/value at a time, then parsing it to determine if it's a number or a string.

    If you guys have any ideas on the design, I'm all ears I wasn't a fan of doing it with a dynamic c-style array, anyhow. It seems too much of a kludge.

  7. #7
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I don't see why that shouldn't be working. Here's what I tried:
    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    
    int main() {
        std::ifstream stream("stringin.txt");
        if(!stream.is_open()) return 1;
        
        std::string first_word;
        // reads a word from the stream, just like using std::cin >> first_word.
        stream >> first_word;
        
        std::string remainder;
        // this reads the remainder of the line.
        std::getline(stream, remainder);
        
        std::cout << "First word in the file: \"" << first_word << "\"\n";
        std::cout << "Remainder of the line:  \"" << remainder << "\"\n";
        
        return 0;
    }
    This is stringin.txt:
    Code:
    This is some data.
    It compiles just fine, and the output is
    Code:
    First word in the file: "This"
    Remainder of the line:  " is some data."
    (Using stream >> string reads one whitespace-delimited word at a time, whereas getline() reads the whole line, up to and including the newline, though the newline is not stored in the variable you provide.)
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  8. #8
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by maxsthekat View Post
    If I do the above, the compiler craps out on me.
    what compiler are you using? I tested with GCC and MSVC2008, and it works fine. in fact, I'm pretty sure the C++ standard specifies an extraction operator (>>) for std::string.

  9. #9
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I'm pretty sure it does too. I used g++ 4.1, but of course that's pretty recent.

    Make sure you're #include'ing <string> . . . .
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  10. #10
    Registered User
    Join Date
    Sep 2009
    Posts
    29
    OMFG!

    I can't believe that... I didn't include string in the first time I tried to do that.

    Wow. Talk about re-inventing the wheel for nothing! Well, at least it provided me a good excuse to learn a bit more about pointers

    Thanks for the tip, guys! I really appreciate it! I was worried I'd always have to keep rewriting similar algorithms every time I wanted to read a file.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. dynamic array malloc()
    By el_chupacabra in forum C Programming
    Replies: 4
    Last Post: 02-12-2009, 07:46 AM
  2. Dynamic pointer array in C
    By MacFromOK in forum Windows Programming
    Replies: 14
    Last Post: 04-09-2005, 06:14 AM
  3. Checking maximum values for dynamic array...
    By AssistMe in forum C Programming
    Replies: 1
    Last Post: 03-21-2005, 12:39 AM
  4. operator overloading and dynamic memory program
    By jlmac2001 in forum C++ Programming
    Replies: 3
    Last Post: 04-06-2003, 11:51 PM
  5. 2D dynamic array problem
    By scsullivan in forum C Programming
    Replies: 3
    Last Post: 12-30-2002, 10:02 PM