Thread: Pointer going out of scope

  1. #1
    Registered User
    Join Date
    Sep 2002
    Posts
    417

    Pointer going out of scope

    How can I get around this without using static?

    In other words, this works fine if the value entered is an int or float.

    If it is a character array (the isint and isdouble functions both returned false), then it assigns the pointer and works correctly inside the overload.

    When the overload ends, the pointer goes out of scope.

    If I use static, it works, but then if you use it again with a different any, it changes BOTH values, which is BAD!

    Code:
    	istream& operator >>(istream & is, any & operand)
    	//precondition:  input stream is open for reading
    	//postcondition: the next string from input stream is has been read
    	//               and stored in operand
    	{
    		static char temp[81];	// not longer than screen length
    		char ch;
    		int i = 0;
        
    		while (i <= 80 && is.get(ch) && ch != '\n')
    			temp[i++] = ch;
    
    		temp[i] = '\0';
    
    		//cout << any_cast<char*>(operand) << endl;
    
    		if (isint(temp))			// if it is an integer, convert it to one
    			operand = atoi(temp);
    		else if (isfloat(temp))		// if it is a float or double, convert it to one
    			operand = atof(temp);
    		else						// otherwise, just store a string
    			operand = temp;
       
    		return is;
    	}

  2. #2
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    What if you replace
    Code:
    else	// otherwise, just store a string
          operand = temp;
    with
    Code:
    else
    {    string s1 = temp;
         operand = s1;
    }
    Would that send a copy of the string, rather than a null pointer, back to the calling function?

  3. #3
    That would probably do something similiar, or the same. There is a built in function to do this easily for you:

    char * strdup( char * );

    Masically, it allocates space for the nre wtring then does a bit-for-bit copy of it, so they don't point to each other anymore.

    ~Inquirer
    Compilers:
    GCC on Red Hat 8.1 (Primary)
    GCC on Mac OS X 10.2.4 (Secondary)

    Others:
    MinGW on XP

  4. #4
    Registered User
    Join Date
    Sep 2002
    Posts
    417
    You're a lifesaver!

    Thanks for the help!

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Don't forget you must free() this string.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    Registered User
    Join Date
    Sep 2002
    Posts
    417
    does free() act like delete?

    So should I remove the static, and change

    operand = temp;

    to

    operand = strdup(temp);

    And then immediately afterwards have

    free(temp); ?

    If you lose it then then there's no point doing this in the first place.

    So if I call free(temp) at the end of the function, will it screw up what is inside the any?

    Is there any way to assign the any the value of the array, without all this other stuff? (without using strings!)

  7. #7
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>does free() act like delete?
    In essence, yes.

    >>So should I remove the static
    Yes

    >>and change
    >>operand = temp;
    >>to
    >>operand = strdup(temp);
    If that's what you want to do.

    >>And then immediately afterwards have
    >>free(temp); ?
    No, free() the memory when you've finished with it, not before.

    >>If you lose it then then there's no point doing this in the first place.
    Exactly.

    >>So if I call free(temp) at the end of the function, will it screw up what is inside the any?
    Yes

    This next bit of code has a bug:
    Code:
    static char temp[81];	
    int i = 0;
    
    while (i <= 80 && is.get(ch) && ch != '\n')
    	temp[i++] = ch;
    
    temp[i] = '\0';
    It has the potential to overflow the buffer. See if you can see why

    [edit]
    strdup() is not a standard function. Don't expect it to work on every compiler.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  8. #8
    What bug does it have? Is it that the loop could end with 80, then assign the 81 [one more than the array has, it stars on 0] to '\0'?

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    It is not?

    I always thought it was...

    But you are right.

    Well, here's a C implementation of strdup():
    Code:
    char *strdup(const char *source)
    {
      return strcpy(malloc(strlen(source)+1), source);
    }
    Note that this one crashes if the malloc call fails, but I just thought it cool when I realized this could be done on one line.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #10
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Originally posted by Inquirer
    What bug does it have? Is it that the loop could end with 80, then assign the 81 [one more than the array has, it stars on 0] to '\0'?
    Kind of, here's the answer in my words:

    The loop could end when this test fails:
    >>while (i <= 80 )
    when it does, i will be 81, which makes this incorrect:
    >>temp[i] = '\0';
    So, to fix, use
    >>while (i < 80 )
    which means the loop will end when i is 80, making the array indexing correct.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  11. #11
    Registered User
    Join Date
    Sep 2002
    Posts
    417
    without dynamically allocating using the strdup, is there any other way to do this? I don't want to dynamically allocate something and then have to have a bool telling it that it was dynamically allocated so that it knows to use free()

    Thanks

  12. #12
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Why don't you simply pass in a std::string instead of char *? It would spare you all the troubles of memory allocation:
    Code:
    operand = std::string(temp);
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  13. #13
    Registered User
    Join Date
    Sep 2002
    Posts
    417
    I keep saying I will NOT do that.

    If the user wants a string, they have to decide that manually.

    Originally posted by Salem
    If you have
    char test[20];
    cin >> test;
    Perhaps you need a garbage collector if you dont/cant remember to free all your allocations...
    http://www.google.com/search?hl=en&i...age+collection
    Its using a class... cin >> object;

    So I can't use strcpy. I have a weird idea... let me try it. Otherwise I'll look up garbage collection.

    Thx!

  14. #14
    Registered User
    Join Date
    Sep 2002
    Posts
    417
    Code:
    		else
    		{// otherwise, just store a string
    			operand = "                                                                                        ";
    			strcpy(static_cast<any::holder<char*> *>(operand.content)->held,temp);
    		}
    Why is this giving me a memory violation? Is it because it doesn't have a size? I don't want to dynamically allocate unless absolutely necessary because it'd make things very ugly
    Last edited by Trauts; 05-08-2003 at 11:06 AM.

  15. #15
    Registered User
    Join Date
    Sep 2002
    Posts
    417
    Is there any way at all to store the data of the array and not the actual pointer?

    I really don't want to use strdup... its not worth it.

    Code:
    			operand = (char*)"                                                                                          ";
    			char * tempbuffer = static_cast<any::holder<char *> *>(operand.content)->held;
    			memccpy(tempbuffer,temp,'\0',81);
    For example, why won't that work? It crashes the program

    It would work to do this: operand = "hello";

    The only problem is i can't do

    const char *temp2 = temp;
    operand = temp2;

    kind of thing because it has the same effect.

    I want to copy the memory, but I definately don't want to dynamically allocate
    Last edited by Trauts; 05-08-2003 at 04:31 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 05-15-2009, 08:38 AM
  2. What is a virtual function pointer?
    By ting in forum C++ Programming
    Replies: 4
    Last Post: 03-05-2008, 02:36 AM
  3. Direct3D problem
    By cboard_member in forum Game Programming
    Replies: 10
    Last Post: 04-09-2006, 03:36 AM
  4. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  5. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM