Garbage in char pointer array

Inside the array sometimes got weird symbol inside

Page 1 of 1

2 Replies - 2888 Views - Last Post: 31 January 2010 - 02:35 PM Rate Topic: -----

#1 gothchicz  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 26-January 10

Garbage in char pointer array

Posted 30 January 2010 - 11:00 AM

Hi,
This assignment suppose to create a set with random character inside it and do some arithmetic function for example Union,Subset,Intersection ..
The character inside the array can't be duplicate.
We suppose to explore pointer and only see the movement pointer in this assignment.

So here is my problem , sometimes i got some weird symbol when i generate the set.
It often appear at the back of the set or when the set is empty set
Could someone please let me know how to terminate char pointer array properly ?
The menu 0 can successfully generate a set with no garbage value
But other function ex : Union,equality ,etc
Sometimes got weird characters inside
(Will only find it if we generate it few times)
But im really curious is there anyway to get rid of this?

Thank you
Sorry for the bad english
Appreciate your help much


#include <iostream>
#include <ctime>
#include <cstdlib>
#include <iomanip>
using namespace std;
const int MAX = 10;

typedef char* ptr;
void constructSet (ptr,int);
void printSet (ptr,ptr);
bool checkSet (char ,ptr ,ptr);
void displaySet (ptr,int);
void addInElement (ptr ,ptr&);
void checkElement (ptr , ptr);
int checkCardinality (ptr , ptr);
void Union (ptr first , ptr last);
void Intersection (ptr first,ptr last);
void complement (ptr first,ptr last);
void complementA (ptr,ptr,ptr,ptr,ptr,ptr);
void complementB (ptr,ptr,ptr,ptr,ptr,ptr);
void subset (ptr first,ptr last);
void equality (ptr,ptr);
int checkEqualityS1 (ptr ,ptr ,ptr ,ptr );
int checkEqualityS2 (ptr ,ptr ,ptr ,ptr );
int generateSize ();

int main ()
{
	
	char a[MAX];
		
	srand( (unsigned int) time(NULL));
	
	int option;
	int size;
	
	do
	{
		cout << "Here are some of the set operations" << endl
			<< endl;
		cout << "0 . An example of set" << endl;
		cout << "1 . Union " << endl;
		cout << "2 . Intersection " << endl;
		cout << "3 . Complement " << endl;
		cout << "4 . Subset of " << endl;
		cout << "5 . Equality " << endl;
		cout << "9 . Quit " << endl 
							<< endl;
		
		cout << "Your choice: ";
		cin >> option;
		cout << endl;
		
		size = generateSize();
		ptr first = &a[0];	  
		ptr last = &a[size-1];	  
			
		switch (option)
		{
			case 0 : displaySet (a ,size);
					 cout << setw(80) << setfill ('-') << " "<<endl;
					break;
			case 1 : Union (first,last);
					 cout << setw(80) << setfill ('-') << " "<<endl;
					break;
			case 2 : Intersection (first,last);
					cout << setw(80) << setfill ('-') << " "<<endl;
					break;
			case 3 : complement (first,last);
					cout << setw(80) << setfill ('-') << " "<<endl;
					break;
			case 4 : subset (first,last);
					cout << setw(80) << setfill ('-') << " "<<endl;
					break;
			case 5 : equality (first,last);
					cout << setw(80) << setfill ('-') << " "<<endl;	 
					break;
		}
		
	}while (option!=9);
	
	return 0;		  
}

int generateSize ()
{
	int size;
	size = rand()%MAX+0;
	return size;
}

void displaySet (ptr s,int size)
{
	int option;
		
	ptr first = &s[0];	  
	ptr last = &s[size-1];		   
	
	cout << setw(80) << setfill ('-') << " "<<endl;	 
	cout << "Here is an example on set of uppercase letters" << endl << endl;
		
	constructSet (s,size);
	cout << " Set S = ";
	printSet (first,last);	 
	
	cout << "Note that elements in S are distinct and are not in order " << endl << endl;
	
	int cardinal;
	do
	{
		cout << "Wish to try the following operations?" << endl;
		cout << " 1. Add an element to the set " << endl;
		cout << " 2. Check an element in set " << endl;
		cout << " 3. Check the cardinality" << endl;
		cout << " 9. Quit" << endl 
							<< endl;
		cout << "Your choice : ";
		cin >> option; 
		cout << endl;
	
		switch (option)
		{
			case 1 : addInElement (first,last);
					cout << setw(80) << setfill ('-') << " "<<endl;	 
					break;
			case 2 : checkElement (first,last);
					cout << setw(80) << setfill ('-') << " "<<endl;	 
					break;
			case 3 :cardinal = checkCardinality (first,last);
					cout << "S has " <<  cardinal << " elements " << endl;
					cout << setw(80) << setfill ('-') << " "<<endl;
					break;
			
		}	 
	}while (option!=9);
	
}

void constructSet (ptr s,int size)
{
	ptr ch;
	ptr first = s;
	int i=0;
	
	while (i<=size)
	{
		ch = new char[size];
		*ch =static_cast <char> ((rand()%26) + 65);
		
		if (checkSet (*ch , first , s)== false)
		{
			*s = *ch;
			++s;
		}
		i++;
	}	 

}
	
void printSet (ptr first,ptr last)
{

	cout << "{";
	
	while (first<last)
	{
		cout << *first << " , ";
		++first;
	}
	cout << *last<< " } ";			 
	cout << endl;
	
}

bool checkSet (char character ,ptr first ,ptr last)
{
	while (first<=last)
	{
		if (character == *first)
			return true;
		else
			first++;
	}
	
	return false;
}

void addInElement (ptr first,ptr& last)
{
	char newElement;
	cout << "Current ";
	printSet (first,last);
	
	cout << "Enter an element : ";
	cin >> newElement;
	
	if (checkSet (newElement ,first,last)==false)
	{
		last++;
		*last = newElement;
	}
	
	cout << " Set S = ";
	printSet (first,last);
}
	
void checkElement (ptr first,ptr last)
{
	char character;
	printSet (first, last);
	
	cout <<"Which element?: ";
	cin >> character;
	cout << endl;
	
	if (checkSet ( character, first , last)==false)
	{
		cout << character << " not in" << " S " << endl;
	}
	else
		cout << character << " is in" << " S " << endl;
		
}

int checkCardinality (ptr first, ptr last)
{
	printSet (first,last);
	int sum = 0;
	
	while (first <=last)
	{
		first++;
		sum++;
	}
	
	return sum;
}


void Union (ptr first,ptr last)
{
	ptr first2;
	ptr last2;
	
	int size1 = generateSize();
	int size2 = generateSize();
	
	char a1 [MAX];
	char a2 [MAX];
	
	cout << "Given the following two sets " << endl;
	cout << "Set S1 = ";
		constructSet (a1 , size1);
		
		first = &a1 [0];
		last = &a1 [size1 - 1];
		printSet (first,last);
		
	cout << "Set S2 = ";
		constructSet (a2 , size2);
		
		first2 = &a2 [0];
		last2 = &a2 [size2 - 1];
		printSet (first2,last2);
	
	while (first <= last)
	{
		if (checkSet (*first , first2 , last2)==false)
		{
			last2++;
			*last2 = *first;
			first++;
		}
		else
		{
			first++;			
		}
	}
	first++;
		
	cout << " The union is : ";
	printSet (first2,last2);

}

void Intersection (ptr first,ptr last)
{
	ptr first2;
	ptr last2;
	ptr first3;
	ptr last3;
		

	int size1 = generateSize();
	int size2 = generateSize();
	
	
	char a1 [MAX];
	char a2 [MAX];
	char b [MAX] = { };
	
	cout << "Given the following two sets " << endl;
	cout << "Set S1 = ";
		constructSet (a1 , size1);
		
		first = &a1 [0];
		last = &a1 [size1 - 1];
		printSet (first,last);
		
	cout << "Set S2 = ";
		constructSet (a2 , size2);
		
		first2 = &a2 [0];
		last2 = &a2 [size2 - 1];
		printSet (first2,last2);
	
		first3 = &b[0];
		last3 = &b[0];
							
	while (first <= last)
	{
		if (checkSet (*first , first2 , last2)==true)
		{			   
			*last3 = *first;	
			last3++;
			first++;	   
		}
		else
		{
			first++;
		}
	}
	last3--;
	
	cout << " The intersection is : ";	   
	printSet (first3,last3);
}

void complement (ptr first,ptr last)
{
	ptr first2;
	ptr last2;
	ptr first3;
	ptr last3;
	ptr first4;
	ptr last4;
		

	int size1 = generateSize();
	int size2 = generateSize();
	
	
	char a1 [MAX];
	char a2 [MAX];
	char b [MAX] = { };
	char c [MAX] = { };
	
	cout << "Given the following two sets " << endl;
	cout << "Set A = ";
		constructSet (a1 , size1);
		
		first = &a1 [0];
		last = &a1 [size1 - 1];
		printSet (first,last);
		
	cout << "Set B = ";
		constructSet (a2 , size2);
		
		first2 = &a2 [0];
		last2 = &a2 [size2 - 1];
		printSet (first2,last2);
	
		first3 = &b[0];
		last3 =first3;
					
		first4 = &c[0];
		last4 = first4;
	 
	complementA (first,last,first2,last2,first3,last3);
	complementB (first,last,first2,last2,first4,last4);	   

}


void complementA (ptr first,ptr last,ptr first2,ptr last2,ptr first3,ptr last3)
{
		// Complements A-B			
	while (first <= last)
	{
		if (checkSet (*first , first2 , last2)==true)
		{			   
			   first++;   
		}
		else
		{
			*last3 = *first;	
			last3++;
			first++;				 
		}
	}
	last3--;
	
	cout << endl;
	cout  << "Complements A-B : ";
	printSet (first3,last3);
}

void complementB (ptr first,ptr last,ptr first2,ptr last2,ptr first4,ptr last4)
{
		//Complements B-A

	while (first2 <= last2)
	{
		if (checkSet (*first2 , first , last)==true) 
		{			   
			first2++;			 
		}
		else
		{
			*last4 = *first2;	 
			last4++;
			first2++;			
		}	 
	}
	last4--;
	
	cout << endl;			
	cout  << "Complements B-A : ";
	printSet (first4,last4);
}

void subset (ptr first,ptr last)
{
	ptr first2;
	ptr last2;
		

	int size1 = generateSize();
	int size2 = generateSize();
	
	char a1 [MAX];
	char a2 [MAX];
	char b [MAX] = { };
	
	cout << "Given the following two sets " << endl;
	cout << "Set A = ";
		constructSet (a1 , size1);
		
		first = &a1 [0];
		last = &a1 [size1-1];
		printSet (first,last);
		
	cout << "Set B = ";
		constructSet (a2 , size2);
		
		first2 = &a2 [0];
		last2 = &a2 [size2-1];
		printSet (first2,last2);
	
	int sum = 0;
	
	while (first <= last)
		{			  
			if (checkSet (*first , first2 , last2)==true)
			{	
					sum++;			   
					first++;
			}
			else
				first++;	   
		}
	
	
	if (sum == size1)
		cout << " A is subset of B" << endl;
	else
		cout  << "A is not subset of B" << endl;					 
}


void equality (ptr first,ptr last)
{
	ptr first2;
	ptr last2;
			

	int size1 = generateSize();
	int size2 = generateSize();
	
	
	char a1 [MAX];
	char a2 [MAX];
	char b [MAX] = { };
	
	cout << "Given the following two sets " << endl;
	cout << "Set A = ";
		constructSet (a1 , size1);
		
		first = &a1 [0];
		last = &a1 [size1 - 1];
		printSet (first,last);
		
	cout << "Set B = ";
		constructSet (a2 , size2);
		
		first2 = &a2 [0];
		last2 = &a2 [size2 - 1];
		printSet (first2,last2);
		
		
	int sizeS1;
	int sizeS2;
	
	if (size1 != size2)
		cout << "It is NOT EQUAL" << endl;
	else 
	{
		sizeS1 = checkEqualityS1 (first,last,first2,last2);
		sizeS2 = checkEqualityS2 (first,last,first2,last2);
		
		if ( (sizeS1 && sizeS2) == true)
			cout << "It is EQUAL" << endl;
		else 
			cout << "It is NOT EQUAL" << endl;
	}
	
}	 

int checkEqualityS1 (ptr first,ptr last,ptr first2,ptr last2)
{
	int sum = 0;
	while (first <= last)
		{
			if (checkSet (*first , first2 , last2)==true)
			{	
					sum++;		
					first++;
			}
			else
					return false;	   
		}
	
	return sum;
}

int checkEqualityS2 (ptr first,ptr last,ptr first2,ptr last2)
{
	int sum = 0;
	while (first2 <= last2)
		{
			if (checkSet (*first2 , first , last)==true)
			{	
					sum++;	  
					first2++;
			}
			else
					return false;  
		}
	
	return sum;
}


 


Is This A Good Question/Topic? 0
  • +

Replies To: Garbage in char pointer array

#2 anonymouscodder  Icon User is offline

  • member icon

Reputation: 126
  • View blog
  • Posts: 710
  • Joined: 01-January 10

Re: Garbage in char pointer array

Posted 30 January 2010 - 11:34 AM

View Postgothchicz, on 30 Jan, 2010 - 03:00 PM, said:

Could someone please let me know how to terminate char pointer array properly ?

You can manually set the null character ('\0'), but make sure that you have allocated memory for the last character.

Your code is a little big, can you specify which part you need help?
Was This Post Helpful? 0
  • +
  • -

#3 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Garbage in char pointer array

Posted 31 January 2010 - 02:35 PM

I didn't check your entire code but the problem that you noticed is occurring in constructSet(). See comments in corrected code:
void constructSet (ptr s,int size)
{
// You must initialize the array before using it. Otherwise checkSet() is
// checking against undefined garbage.
	for( int j = 0; j < size; ++j ) {
		*(s + j) = -1;
	}
//	ptr ch; // see comment below
	char ch;
	ptr first = s;
	int i=0;
   
	while (i<size) // not i <= size; when i==size you are beyond the end of the array
	{
//  Why are you creating a local array when you only need one char? (Notice that you have
//	been using only the first element of this array.)
//		ch = new char[size];
//		*ch =static_cast <char> ((rand()%26) + 65); // *ch is FIRST element in local array
// In the following, ch is a char:
		ch = static_cast <char> ((rand()%26) + 65);
		if (checkSet (ch , first , s)== false) 
		{
			*s = ch;
			++s;
			++i; // moved here instead
		}
//		i++; // Not here; this moves on to the next element even when
			   // the if condition fails, leaving an element undefined.
	}
}



You have another serious error in Union(). Although you may not have encountered it yet, it can cause corrupted data or a segmentation fault. In that function, you allocate memory for two arrays of size MAX. You then add elements from the first array to the end of the second array. But the set union could be as big as 2*MAX so it is very likely that you will at times write beyond the bounds of that array. Therefore, you should make the receiving (second) array twice as big.

By the way, since you are (correctly) handling these arrays as ordinary arrays, not strings, the string termination character '\0' is irrelevant here. But YOU have to make sure that your code keeps track of the array bounds. The compiler won't do it for you.

This post has been edited by r.stiltskin: 31 January 2010 - 02:37 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1