Thread: Access violation with strcpy()

  1. #1
    Registered User
    Join Date
    Apr 2002
    Posts
    80

    Access violation with strcpy()

    Hi guys and gals,

    I'm running into an access violation with strcpy(). I don't use c strings much, so perhaps I'm doing something moronic.

    Any clues?

    Code:
    void getData(vector<char*>& directories, Word& wordStruct)
    {
        ifstream in;
        string temp, temp2;
        int i = 0, j = 0;
        for (i = 0; i < 3; i++)
        {
            if (i == 0)
                in.open("f1.txt");
            if (i == 1)
                in.open("f2.txt");
            if (i == 2)
                in.open("f3.txt");
            while(in)
            {
                getline(in, temp);
                for (j = 0; j < temp.size(); j++)
                {
                    if (isalpha(temp[j]))
                        temp2 = temp2 + temp[j];
                    else
                    {
                        Files files;
                        files.setWord(temp2.c_str());
                        wordStruct.addWord(files, i);
                        temp2 = "";
                    }
                }
                
            }
            in.close();
        }
    }
    
    
    void setWord(const char* w)
        { strcpy(word,w); }           // Problem is here. word is a char*
    Last edited by BigDaddyDrew; 03-24-2003 at 12:36 AM.

  2. #2
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    The declaration of Word would really help. Is it "just" a char*, then it is poitning to a random spot in memory and probably the source of your access violation.
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  3. #3
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >// Problem is here. word is a char*
    That could very likely be your problem. Unless word is a char pointer with memory allocated to it, or it points to an array, you probably don't have write access to what it points to.

    -Prelude
    My best code is written with the delete key.

  4. #4
    Registered User
    Join Date
    Apr 2002
    Posts
    80
    Yeah, you guys are probably right....

    I guess to me, it didn't matter that there wasn't any memory allocated to word*, as strcpy would take care of that...

    Here is word:

    Code:
    class Files
    {
    private:
        vector<int> fileList;
        char* word;
    
    public:
        void addFile(int);
        char* getWord()
        { return word; }
        void setWord(const char* w)
        { strcpy(word,w); }
        void printFile();
    
    
    };
    
    void Word::resize()
    {
        int newSize, index;
        list<Files> tempList;
        Files tempFile;
        for (int i = 0; primes[i] < table.size(); i++)
        {
            newSize = primes[i+1];
        }
    
        vector<list<Files> > newTable = table, newTable2(newSize);
        table = newTable2;
    
        for (i = 0; i < newTable.size(); i++)
        {
            tempList = table.back();
            table.pop_back();
            for (int j = 0; j < tempList.size(); j++)
            {
                tempFile = tempList.front();
                tempList.pop_front();
                index = hash(tempFile.getWord(), table.size());
                table[index].push_front(tempFile);  
            }
        }
        return;
    }
    
    void Word::addWord(Files file, int fileNum)
    {
        int index = hash(file.getWord(), table.size());
        list<Files>::iterator it;
    
        for (it = table[index].begin(); it != table[index].end(); it++ )
        {
            if (it == table[index].end())
            {
                table[index].push_front(file);
            }
            else if (!strcmp(it->getWord(),file.getWord()))
            {
                it->addFile(fileNum);
            }
            
        }
    }
    
    void Word::print()
    {
        list<Files>::iterator it;
        for (int i = 0; i < table.size(); i++)
        {
            cout << i << " ";
            for(it = table[i].begin(); it != table[i].end(); i++)
            {
                it->printFile();
            }
            cout << endl;
        }
    }

  5. #5
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >as strcpy would take care of that...
    No, it's your job to make sure that strcpy receives valid arguments, including enough memory in the buffer being copied to.

    On a side note, your Files class should have a constructor that places an object in a well defined state immediately. Anything else is just asking for trouble. As it is, word has an indeterminate value.

    -Prelude
    My best code is written with the delete key.

  6. #6
    Registered User
    Join Date
    Apr 2002
    Posts
    80
    If I created a default constructor that initialized the word pointer to NULL, would that get the job done?

  7. #7
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856
    If I created a default constructor that initialized the word pointer to NULL, would that get the job done?
    No bloody way. Were you to do that, any attempt to access the data pointed to by `word` would result in an access of the address zero.
    Try `new` and `delete []`or `char word[100]`

  8. #8
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Were you to do that, any attempt to access the data pointed to by `word` would result in an access of the address zero.
    word is a private member though. The class only allows access to it by way of getWord and setWord. If word were initialized to a null pointer then those functions could be made more safe because there's something to check for. Otherwise even attempting to access word would result in undefined behavior.

    -Prelude
    My best code is written with the delete key.

  9. #9
    Registered User
    Join Date
    Apr 2002
    Posts
    80
    Heh, ok, forgive my retardation....however, I don't want to limit myself to, say, 100 chars. I don't know the length of the words I'll be reading in....perhaps this needs to be explained to me in a dummy fashion! What is the best/only way to stay with a char*, but to not run into problems with access violations with strcpy() and the like?

    Thanks!

  10. #10
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856
    Please don't misinterpret my point. I'm not saying that initializing word to NULL is a bad thing. My only point is that it looked to me as if bigPuffDaddy was thinking all he had to do was set word to NULL and his problems would be gone.
    Actually, I just scrolled down and now realize I missed an important thing he said illustrating that he was already aware he needed to `new` some memory:
    I guess to me, it didn't matter that there wasn't any memory allocated to word*
    Pardon my zinger.

  11. #11
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    If you don't want a limit on the string, allocate memory at runtime:
    Code:
    Files::Files()
    {
       Word = NULL;
    }
    
    Files::~Files()
    {
       if(Word != NULL) delete[] Word;
       Word = NULL;
    }
    
    void Files::SetString(const char* NewString)
    {
       //Deallocate the old string
       if(Word != NULL) delete[] Word;
       Word = NULL;
    
       //Only clear the word if you pass NULL
       if(NewString == NULL) return;
    
       //Allocate memory for the new string
       Word = new char[strlen(NewString) + 1];
       if(Word != NULL)
       {
          strcpy(Word, NewString);
       }
    }
    EDIT:
    Am I the only one reacting to the class being named Files but the methods belonging to Word:: ???
    Last edited by Magos; 03-24-2003 at 03:34 PM.
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  12. #12
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856
    Am I the only one reacting to the class being named Files but the methods belonging to Word:: ???
    Actually the Word:: functions use lists of Files.

  13. #13
    Registered User
    Join Date
    Apr 2002
    Posts
    80
    That last code looks good..

    And regarding the class/methods....I was being a moron again and copied the wrong functions into the post...I was in a hurry to get to work when I did it!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Access Violation using memcmp?
    By someprogr in forum C Programming
    Replies: 3
    Last Post: 12-31-2007, 01:45 AM
  2. Access violation... can't figure it out...
    By Raigne in forum C++ Programming
    Replies: 7
    Last Post: 10-11-2007, 10:52 AM
  3. FtpFileFind access violation with MS VC++ 6.0
    By earth_angel in forum C++ Programming
    Replies: 3
    Last Post: 09-22-2005, 07:02 PM
  4. Array of pointers + strcpy = access violation?
    By DarkDragon in forum C Programming
    Replies: 2
    Last Post: 09-09-2002, 01:56 AM
  5. 0xC0000005: Access Violation
    By Strider in forum Windows Programming
    Replies: 3
    Last Post: 11-07-2001, 02:46 PM