CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 19

Thread: How to use set<char*>?

  1. #1
    Join Date
    Jul 2005
    Posts
    1,030

    How to use set<char*>?

    Here is the code. Both set1 and set2 always store one string. I know why but I don't know how to use set<char*> and still allow me to store multiple strings? Thanks.
    Code:
    void PrintOut(const char* fileName)
    {
    	char line[256];
    	set<char*> set1;
    	set<char*> set2;
    	char key[64];
    	char def[64];
    	char* pLine;
    
    	int index1;
    	int index2;
    
    	int count;
    
    	FILE* file = fopen(fileName, "r");
    
    	while(fgets(line, 64, file))
    	{
    		index1 = 0;
    		index2 = 0;
    		count = 0;
    		pLine = line;
    		while(*pLine)
    		{
    			if(count == 0)
    				key[index1++] = *pLine;
    			else
    				def[index2++] = *pLine;
    
    			if(*pLine == ' ')
    			{
    				if(*(pLine+1) == '.')
    					break;
    
    				if(count == 0)
    				{
    					key[index1] = '\0';				
    					set1.insert(key);
    					index1 = 0;
    				}
    				else
    				{
    					def[index2] = '\0';					
    					set2.insert(def);
    					index2 = 0;
    				}
    				count++;
    			}
    
    			pLine=pLine+1;
    		}
    
    		def[index2] = '\0';
    		set2.insert(def);		
    	}
    
    	set<char*>::iterator next;
    	for(set<char*>::iterator it2=set2.begin();it2!=set2.end();++it2)
    	{
    		for(set<char*>::iterator it1=set1.begin();it1!=set1.end();it1=next)
    		{
    			next = it1;
    			next++;
    			if(*it1 == *it2)
    				set1.erase(*it1);
    		}
    	}
    	fclose(file);
    }

  2. #2
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,316

    Re: How to use set<char*>?

    They both displays the last string, right? That's because you are storing the pointer to the same string buffer. Try defining the set as set key<string>.

  3. #3
    Join Date
    Jul 2005
    Posts
    1,030

    Re: How to use set<char*>?

    Quote Originally Posted by Arjay View Post
    They both displays the last string, right? That's because you are storing the pointer to the same string buffer. Try defining the set as set key<string>.
    I understand that. But my question is that is it still possible to store multiple strings in a set without using stl string? Thanks.

  4. #4
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,189

    Re: How to use set<char*>?

    Yes it is. Rather than have key and def defined as fixed items on the stack, create them as dynamic elements on the heap (use new) each time round the while loop. You'll need to also free the memory as part of the function clean up.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.7.0)

  5. #5
    Join Date
    Jul 2005
    Posts
    1,030

    Re: How to use set<char*>?

    Quote Originally Posted by 2kaud View Post
    Yes it is. Rather than have key and def defined as fixed items on the stack, create them as dynamic elements on the heap (use new) each time round the while loop. You'll need to also free the memory as part of the function clean up.
    Thanks for your reply! If I free the memory, then the string stored in the set1 and set2 will be destroyed. Here is my modified code. Would you tell me how to free the memory? Thanks.
    Code:
    void PrintOut(const char* fileName)
    {
    	char line[256];
    	set<char*> set1;
    	set<char*> set2;
    	char key[64];
    	char def[64];
    	char* pKey;
    	char* pDef;
    	char* pLine;
    
    	int index1;
    	int index2;
    
    	int count;
    
    	FILE* file = fopen(fileName, "r");
    
    	while(fgets(line, 64, file))
    	{
    		index1 = 0;
    		index2 = 0;
    		count = 0;
    		pLine = line;
    		while(*pLine)
    		{
    			if(count == 0)
    				key[index1++] = *pLine;
    			else
    				def[index2++] = *pLine;
    
    			if(*pLine == ' ')
    			{
    				if(*(pLine+1) == '.')
    					break;
    
    				if(count == 0)
    				{
    					key[index1] = '\0';	
    					pKey = new char[index1+1];
    					strcpy(pKey, key);
    					set1.insert(pKey);
    					index1 = 0;
    				}
    				else
    				{
    					def[index2] = '\0';					
    					pDef = new char[index2+1];
    					strcpy(pDef, def);
    					set2.insert(pDef);
    					index2 = 0;
    				}
    				count++;
    			}
    
    			pLine=pLine+1;
    		}
    
    		def[index2] = '\0';
    		pDef = new char[index2+1];
    		strcpy(pDef, def);
    		set2.insert(pDef);		
    	}
    
    	set<char*>::iterator next;
    	for(set<char*>::iterator it2=set2.begin();it2!=set2.end();++it2)
    	{
    		for(set<char*>::iterator it1=set1.begin();it1!=set1.end();it1=next)
    		{
    			next = it1;
    			next++;
    			if(*it1 == *it2)
    				set1.erase(*it1);
    		}
    	}
    	fclose(file);
    }

  6. #6
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,597

    Re: How to use set<char*>?

    Quote Originally Posted by LarryChen View Post
    Thanks for your reply! If I free the memory, then the string stored in the set1 and set2 will be destroyed. Here is my modified code. Would you tell me how to free the memory? Thanks.
    He said cleanup Larry. That means you free the memory when you're done with it. As to how you do it, I would think after nine years on this forum, you'd know that delete is used to free memory allocated with new.

  7. #7
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,316

    Re: How to use set<char*>?

    Along with cleanup, it's important to understand what the following line does.

    set1.erase(*it1);

    Questions for Larry:
    Does it remove the item from the set?
    Does it free up the item pointed to by *it1 ?

  8. #8
    Join Date
    Jul 2005
    Posts
    1,030

    Re: How to use set<char*>?

    Quote Originally Posted by GCDEF View Post
    He said cleanup Larry. That means you free the memory when you're done with it. As to how you do it, I would think after nine years on this forum, you'd know that delete is used to free memory allocated with new.
    Congratulations! You know delete! You are a GURU in C++. But would you please spare a second to read my post? Thanks.

  9. #9
    Join Date
    Jul 2005
    Posts
    1,030

    Re: How to use set<char*>?

    Quote Originally Posted by Arjay View Post
    Along with cleanup, it's important to understand what the following line does.

    set1.erase(*it1);

    Questions for Larry:
    Does it remove the item from the set?
    Does it free up the item pointed to by *it1 ?
    Yes, it does remove the item from the set1. But I am not sure if set1.erase(*it1) will free the memory pointed by *it1. Any idea? Thanks.

  10. #10
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,316

    Re: How to use set<char*>?

    Quote Originally Posted by LarryChen View Post
    Yes, it does remove the item from the set1. But I am not sure if set1.erase(*it1) will free the memory pointed by *it1. Any idea? Thanks.
    Larry, why ask the question?

    Use the debugger and find out. Put a breakpoint on the set1.erase(...) line and inspect the *it1 value in the watch or local window. Then single step through just past the line and inspect the value again.

    If you can't do this in your project, then create a test project that does the same thing.

    Report back.

  11. #11
    Join Date
    Jul 2005
    Posts
    1,030

    Re: How to use set<char*>?

    Quote Originally Posted by Arjay View Post
    Larry, why ask the question?

    Use the debugger and find out. Put a breakpoint on the set1.erase(...) line and inspect the *it1 value in the watch or local window. Then single step through just past the line and inspect the value again.

    If you can't do this in your project, then create a test project that does the same thing.

    Report back.
    Yes, erase does free the memory. Thanks.

  12. #12
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,316

    Re: How to use set<char*>?

    Quote Originally Posted by LarryChen View Post
    Yes, erase does free the memory. Thanks.
    Are you sure you are using the debugger correctly?

  13. #13
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,717

    Re: How to use set<char*>?

    1) I agree with Arjay, you need to recheck. Hint: You initial code did not crash.

    2) using char * leads to lots of problems. Consider:

    Code:
        set<char *> set1;
    
        char * p1 = new char[10];
        char * p2 = new char[10];
    
        strcpy(p1,"hello");
        strcpy(p2,"hello");
    
        set1.insert(p1);
        set1.insert(p2);
    This will result in a set of size 2 (probably not what you want). This is because by default, the
    comparison function will be operator <. This will just order by the address.

    You will need to use the set constructor where you specify the comparison function.
    Even after doing that, you will need to check that the string is in the set before
    trying to insert it. If it is already in the set, the insert will fail, and will not be
    deleted when you end up doing the eventual delete.

    You might consider using smart pointers instead of raw pointers.
    Last edited by Philip Nicoletti; October 3rd, 2014 at 10:06 PM. Reason: forgot the second strcpy

  14. #14
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,189

    Re: How to use set<char*>?

    Quote Originally Posted by LarryChen View Post
    I understand that. But my question is that is it still possible to store multiple strings in a set without using stl string? Thanks.
    Why do you want to use set<char*>? Why not just use set<string> as it's far easier - you haven't got to bother with a comparison function and issues re allocating and freeing memory.

    What is the format of your file layout and what are you trying to achieve?
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.7.0)

  15. #15
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,597

    Re: How to use set<char*>?

    Quote Originally Posted by LarryChen View Post
    Congratulations! You know delete! You are a GURU in C++. But would you please spare a second to read my post? Thanks.
    You asked how to free memory. I told you. You seem confused by some very basic concepts, so I gave you a very basic answer.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)