[C++] Segmentation Fault {Novice C++ Programmer}

This is a discussion on [C++] Segmentation Fault {Novice C++ Programmer} within the C++ Programming forums, part of the General Programming Boards category; Im still confused....

  1. #16
    Registered User
    Join Date
    Nov 2004
    Posts
    93
    Im still confused.

  2. #17
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    This function will change any i in the string sent in to an a.
    Code:
    void changeIToA(char * str)
    {
    	int m, j;
    	j = strlen(str);
    	for(int m = 0; m < j; ++m)
    	{ 
    	 if(str[m] == 'i')
    		 str[m] = 'a';
    	}
    	cout << str << endl;
    }

    Then let's say you have this in main()

    char * s = "Mississippi";

    So s is a string literal. If you pass s to changeIToA() you will get an error, because you cannot change string literals, but that's what changeIToA() will try to do. So you need to pretend to manipulate a string literal by copying the string literal into a char array and use that instead;
    Code:
    void changeIToA(char * str)
    {
    	int m, j;
    	j = strlen(str);
     
    	char temp[80];
    	strcpy(temp, str);
     
    	for(m = 0; m < j; ++m)
    	{ 
    	 if(temp[m] == 'i')
    		 temp[m] = 'a';
    	}
    	cout << temp << endl;
    }
    now it doesn't matter whether you pass a non string literal char array or a string literal to changeItoA() because whatever type of C style string you send, it will be copied into temp and temp will be modified, and you will not be changing the string sent in at all.
    Last edited by elad; 06-08-2005 at 10:57 AM.
    You're only born perfect.

  3. #18
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,499
    Well break your massive "do it all" function into smaller functions which do specific tasks.
    - removeLeadingSpaces
    - removeTrailingSpaces
    - packSpaces
    Test each one to make sure it works before implementing the next one.

    When you're done, your int Account::cleanSpace(char c[]) simply calls those 3 sub-functions in turn.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  4. #19
    Registered User
    Join Date
    Nov 2004
    Posts
    93
    Yes but my function is not passed in a pointer, it is passed by copy. Same with in main (I can not change main as it is used to test our implementation files with)

  5. #20
    Registered User
    Join Date
    Nov 2004
    Posts
    93
    Tried this. I take in a pointer, make a buffer, copy it to the buffer, manipulate buffer, change it back to the pointer.

    Same seg fault.

    What am I interpreting wrong in your suggestions?

    Code:
    int cleanSpace(char* ptr)
    {  
    
    	char temp[251];
    	strcpy(temp, ptr);
     
        int i=0,
            j=0,
            k=0, 
            m=0; 
            
       /* Ultimately this loop will scan for new lines and tabs and replace them 
       with spaces. */
        for(i=0; temp[i]; i++)
        {   
    	    if(temp[i] == '\n' || temp[i] == '\t')
    	    temp[i] = ' ';     
        }
    
       /* For loop finds character starting point. */
        for(i=0; temp[i] == ' '; i++)
        {
            temp[m] = temp[i+1];
        }         
    	     
       /* For loop moves all characters next to the first found character. */
        for(i++; temp[i]; i++)
        {
            temp[++m] = temp[i];
        }
    
       /* For loop removes trailing spaces. */
        for(i = strlen(temp) - 1; temp[i] == ' '; i--)
        {
            temp[i] = '\0';
        }
    
       /*For loop removes excess spaces. */
        for(i = 0; temp[i]; i++)
        {
            if(temp[i] == ' ' && temp[i+1] == ' ')
            {
                j = i;
                
        	    while(temp[j] == ' ')
                {
    	           j++;
                } 
    	    
        	    for(k = i + 1; temp[k]; k++, j++)
                {
        		      temp[k] = temp[j];
        	    }
            j=0;                           
    	   }
        }
        strcpy(ptr,temp);
        return strlen(ptr);
    Last edited by INFERNO2K; 06-08-2005 at 11:56 AM.

  6. #21
    Registered User
    Join Date
    Nov 2004
    Posts
    93
    Same seg fault on
    Code:
      /* For loop moves all characters next to the first found character. */
        for(i++; temp[i]; i++)
        {
            temp[++m] = temp[i];
        }

  7. #22
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    >>my function is not passed in a pointer, it is passed by copy

    You may think the following means you're passing c by copy, but it's not.

    int Account::cleanSpace(char c[]){...

    The above is equivalent to:

    int Account::cleanSpace(char * c){...

    If c is a string literal then you can't change any of the char of c by idividual char changes as in

    if(c[i] == 'i')
    c[i] = 'a';

    or as in

    strcpy(c, temp);

    where temp started life as a copy of c, temp was changed during the course of the function, and now you're trying to change c by copying temp into it.
    ________________________________________
    As to the individual loops, I think Salem's suggestion is excellent. If you don't want to break the one function up into several, comment out all loops except the first one and then print out temp after each loop to make sure it works before moving on the next loop. etc.

    It looks to me like you're preincrementing m going from the second to third loop, but post incrementing i:

    for(i++;

    Since m was equal to i + 1 in the second loop it seems to me that you may be making two copies of the same char.....but you really need to check it out for yourself as outlined above.
    You're only born perfect.

  8. #23
    Registered User
    Join Date
    Nov 2004
    Posts
    93
    So it is necessary to make temp than correct?

  9. #24
    Registered User
    Join Date
    Nov 2004
    Posts
    93
    I think I just discovered the problem.

    Since this function is loaded a few times, the temp array is getting overfilled. It can not hold the contents so it crashes.

    I need a way to clear the array or destroy the array and recreate it at the end and beginning of the function.

  10. #25
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    The following program uses your syntax and the cleanSpace function as a prototype for your program. This technique of simplifying problems in separate programs and then using that technique in the real progam is a useful technique to learn.

    In this program I have heavily commented using output statements each time something changed, so I can follow the flow without using a debugger.

    I gave you the first fix I found for free. You can reuse it later. I've left the for loop for removing internal spaces open though I've given you a very rough pseudocode as to how to fill in the blanks left in the loops you had, which were correct in number and type but had incorrect condtions, etc. The loop for shifting to the left was reading beyond bounds which was the problem rather than needing to clear the array as you suggested in your last post. I attacked each if statement and loop with as many comments as I did the preceding loop until I got it correct.

    When I got it correct using a char [] I then tried it with a string literal, and promptly got a terminal error report at the part where the corrected temp array was copied back into ptr. You'll be able to see it for yourself once you get the loop to remove internal spaces up and running.

    Good luck. Hope you're finding the process educational.

    Code:
    #include <iostream>
    using namespace std;
    
    int cleanSpace(char* ptr)
    {  
    
     char temp[251];
     strcpy(temp, ptr);
      cout << "origninal temp" << endl;
      cout << temp << endl;
     
    	int i=0,
    		j=0,
    		k=0, 
    		m=0; 
    		
       // Ultimately this loop will scan for new lines and tabs and replace them 
       //with spaces. 
    	for(i=0; temp[i]; i++)
    	{   
    	 if(temp[i] == '\n' || temp[i] == '\t')
    	 temp[i] = ' ';	 
    	}
    	cout << "temp after removal of newlines and tabs" << endl;
    	cout << temp << endl;
    
       // For loop finds character starting point. 
    	for(i=0; temp[i] == ' '; i++)
    	{
    		temp[m] = temp[i+1];
    	}		 
    	  
       // For loop moves all characters next to the first found character. 
    	for(i++; temp[i]; i++)
    	{
    		temp[++m] = temp[i];
    	}
    	temp[m+1] = '\0';  //here's the freebie
    	
    	cout << "temp after removing leading spaces " << endl;
    	cout << temp << endl;
    	cout << "temp length = " << strlen(temp) << endl;
    
    	// For loop removes trailing spaces. 
    	for(i = strlen(temp) - 1; temp[i] == ' '; i--)
    	{
    		temp[i] = '\0';
    	}
    	cout << "temp after removing trailing spaces" << endl;
    	cout << temp << endl;
    	cout << "temp length = " << strlen(temp) << endl;
    
       //For loop removes internal spaces. 
    	for(i = 0; temp[i]; i++)
    	{
    	  //if temp[i] is a space
    	  //then set j to be the index of the first space in this sequence of spaces.
    	  //Note: there may be one or more spaces in any given sequence of spaces.
    	  //use an internal loop to determine how many spaces there are in this sequence.
    	  //use a second internal loop to shift all char beyond current sequence
    	  //to the left by the number of spaces in this sequence
    	  //be sure there is a terminating null char at the end of temp after each shift completed
    	  //reset any internal counters to zero for next sequence, if any
    
    		if()		 
    		{
    			while()
    			{
    			} 
    	 
    			for()
    			{
    			}
    		}
    	}
    	cout << "temp after removing internal spaces" << endl;
    	cout << temp << endl;
    	cout << "temp length = " << strlen(temp) << endl;
    	
    	strcpy(ptr,temp);
    	return strlen(ptr);
    }
    
    int main()
    {
      char str[40] = "  Hit\tit\n\te  "; ;
      int i = cleanSpace(str);
      cout << i << endl;
    
      char ch;
      cin >> ch;
    
      char * p = "  Hit\tit\n\te  ";
      i = cleanSpace(p);
      cout << i << endl;
      return 0;
    }
    You're only born perfect.

Page 2 of 2 FirstFirst 12
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation fault
    By bennyandthejets in forum C++ Programming
    Replies: 7
    Last Post: 09-07-2005, 05:04 PM
  2. Segmentation fault
    By NoUse in forum C Programming
    Replies: 4
    Last Post: 03-26-2005, 02:29 PM
  3. Locating A Segmentation Fault
    By Stack Overflow in forum C Programming
    Replies: 12
    Last Post: 12-14-2004, 12:33 PM
  4. Segmentation fault...
    By alvifarooq in forum C++ Programming
    Replies: 14
    Last Post: 09-26-2004, 12:53 PM
  5. Rtfm
    By XSquared in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 03-13-2003, 04:19 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21