Picture download problem

This is a discussion on Picture download problem within the C Programming forums, part of the General Programming Boards category; Hello, I`m working on downloading map from map server. When I download one map, everything runs ok. But I have ...

  1. #1
    Registered User
    Join Date
    Jul 2007
    Posts
    6

    Picture download problem

    Hello,

    I`m working on downloading map from map server.
    When I download one map, everything runs ok. But I have to download 20 small maps and join them together to
    get big one. The first should be downloaded and saved as mapycz00, then second map should be downloadedand
    saved as mapycz01, third map should be downloaded and saved as mapycz03 and so on...
    To do this, I`ve got cycle in which I call procedure to download file.
    But this doesn`t work. It works like that, it downloads one map and saves it as mapycz00, mapycz01
    and mapycz02, then it downloads another map and saves it as mapycz03, mapycz04 and that is all.

    Here is part of the code:

    Code:
    /* *****************************************************************************
     */
    gint
    main_function (GtkWidget * widget, guint datum)
    {
    	/* which map in order is going to be downloaded? */
    	mapyczcount = 0;
    
    	int j;
    	for (j = 0; j <= 19; j++)
    	{
    		while (gtk_events_pending ())
    				gtk_main_iteration ();
    
    		downloadstart_cb(widget, datum, writebuff);
    		/* writebuff is char array, contents all info for server and seems to work ok */
    	}
    }
    
    gint
    downloadstart_cb (GtkWidget * widget, guint datum, gchar writebuff3[2000])
    {
        struct sockaddr_in server;
        struct hostent *server_data;
        gchar str[100], sn[1000];
    
        downloadfilelen = 0;
        downloadactive = TRUE;
      
        while (gtk_events_pending ())
    	gtk_main_iteration ();
    
        /*  open socket to port80 */
        if ((dlsock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
    	{
    	    perror (_("can't open socket for port 80"));
    	    return (FALSE);
    	}
    
        server.sin_family = AF_INET;
        /*  We retrieve the IP address of the server from its name: */
        if (haveproxy)
    	g_strlcpy (sn, proxy, sizeof (sn));
        else
    	{
    	    g_strlcpy (sn, WEBSERVER, sizeof (sn));
    	}
    
        if ((server_data = gethostbyname (sn)) == NULL)
    	{
    	    perror (_("Can't resolve webserver address"));
    	}
    
        memcpy (&server.sin_addr, server_data->h_addr, server_data->h_length);
        server.sin_port = htons (proxyport);
        /*  We initiate the connection  */
        if (connect (dlsock, (struct sockaddr *) &server, sizeof server) < 0)
    	{
    	    perror (_("unable to connect to Website"));
    	}
    
        write (dlsock, writebuff3, strlen (writebuff3));
    	printf ("dlsock: %d, writebuff3: %s\n", dlsock, writebuff3);
    
    	dlbuff = g_new0 (gchar, 8192);
       	dlpstart = NULL;
    	dldiff = dlcount = 0;
    	g_snprintf (str, sizeof (str), _("Now connected to %s"),
    		   			WEBSERVER);
    		
       	gtk_timeout_add (100, (GtkFunction) downloadslave_cb, widget);
    
    	return TRUE;
       
    }
    
    gint
    downloadslave_cb (GtkWidget * widget, guint datum)
    {
        if (!downloadwindowactive ))  
    		return FALSE;
    
    	FD_ZERO (&readmask);
        FD_SET (dlsock, &readmask);
        timeout.tv_sec = 0;
        timeout.tv_usec = 100000;
        if (select (FD_SETSIZE, &readmask, NULL, NULL, &timeout) < 0)
    	{
    	    perror ("select() call");
    	}
    
        if (FD_ISSET (dlsock, &readmask))
    	{
    	    memset (tmpbuff, 0, 8192);
    	    if ((e = read (dlsock, tmpbuff, 8000)) < 0)
    			perror (_("read from Webserver"));
    	    
    	    if (e > 0)
    		{
    		    /*  in dlbuff we have all download data */
    			memcpy ((dlbuff + dlcount), tmpbuff, e);
    		    /*  in dlcount we have the number of download bytes */
    		    dlcount += e;
    		    /* now we try to get the filelength and begin of the gif image data */
    		    if (dlpstart == NULL)
    			{
    			    /*  CONTENT-LENGTH string should hopefully be in the first 4kB */
    			    memcpy (tmpbuff, dlbuff, 4096);
    			    /*  We make of this a null terminated string */
    			    tmpbuff[4096] = 0;
    			    g_strup (tmpbuff);
    			    p = strstr (tmpbuff, "CONTENT-LENGTH:");
    			    if (p != NULL)
    				{
    				    sscanf (p, "%s %d", str,
    					    &downloadfilelen);
    				    /*  now we look for 2 cr/lf which is the end of the header */
    				    dlpstart = strstr (tmpbuff, nn);
    				    dldiff = dlpstart - tmpbuff + 4;
    				}
    			    else if (dlcount > 1000)
    				{
    				    /*  Seems there is no CONTENT-LENGTH field  */
    				    dlpstart = strstr (tmpbuff, nn);
    				    dldiff = dlpstart - tmpbuff + 4;
    				    downloadfilelen = 200000;
    				}
    			}
    		    /*  Now we have the length and begin of the gif image data */
    		    if ((downloadfilelen != 0) && (dlpstart != NULL))
    			{
    			    dlbuff = g_renew (gchar, dlbuff,
    					      dlcount + 8192);
    			    
    			    g_snprintf (str, sizeof (str),
    					_("Downloaded %d kBytes"),
    					(dlcount - dldiff) / 1024);
    			   
    			    while (gtk_events_pending ())
    				gtk_main_iteration ();
    			}
    
    		}
    	    if ((e == 0) || ((downloadfilelen + dldiff) == dlcount))
    		{
    
    		    if (downloadfilelen == 0)
    			g_snprintf (str, sizeof (str),
    				    _("Download FAILED!"));
    		    else
    			g_snprintf (str, sizeof (str),
    				    _("Download finished, got %dkB"),
    				    dlcount / 1024);
    		   
    		    close (dlsock);
    		    if (downloadfilelen != 0)
    			{
    				// save downloaded picture 
    
    			    s = gtk_entry_get_text (GTK_ENTRY (dltext));
    			    if (local_config.dir_home[strlen (local_config.dir_home) - 1] != '/')
    				g_strlcat (local_config.dir_home, "/",
    					   sizeof (local_config.dir_home));
    
    				g_strlcpy (downloadfilename, local_config.dir_home,
    					       sizeof (downloadfilename));
    
    				g_snprintf (s2, sizeof (s2),
    				    			_("mapycz%d"), mapyczcount);
    				g_strlcat (downloadfilename, s2,
    					       sizeof (downloadfilename));
    
    				fd = open (downloadfilename,
    						    O_RDWR | O_TRUNC | O_CREAT, 0644);
    					
    				write (fd, dlbuff + dldiff, dlcount - dldiff);
    				close (fd);
    
    				if (mapyczcount == 19)
    				{
    					// save info about big picture
    					g_strlcpy (downloadfilename, local_config.dir_home,
    					       sizeof (downloadfilename));
    				   	g_strlcat (downloadfilename, s,
    					       sizeof (downloadfilename));
    					
    					// now join 20 small pictures together and make big one and save it
    					// ... 
    						
    				}
    					else
    						mapyczcount++;
    				}
    			}
    
    		    downloadwindowactive = FALSE;
    		    gtk_widget_destroy (downloadwindow);
    		    gtk_timeout_add (3000, (GtkFunction) dlstatusaway_cb, widget);
    
    		    return FALSE;
    		}
    	}
        else
    	{
    	    return TRUE;
    	}
    
    
        return TRUE;
    }
    Where the problem could be? I`m quit desperate.
    Thanks in advance.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    From what I can see, you only have ONE download buffer (dlbuff) - overwriting the same buffer each download.

    Of course, I haven't got all the code for your project, so I don't really know.

    Another potential problem in the future (when this is being run for a longer time) is that you're leaking open "dlsock" handles - at least if something happens that makes the code not run the code here:
    Code:
    	    if ((e == 0) || ((downloadfilelen + dldiff) == dlcount))
    		{
    
    		    if (downloadfilelen == 0)
    			g_snprintf (str, sizeof (str),
    				    _("Download FAILED!"));
    		    else
    			g_snprintf (str, sizeof (str),
    				    _("Download finished, got %dkB"),
    				    dlcount / 1024);
    		   
    		    close (dlsock);
    You probably want to move the close(dlsock) call to some other place where it's ALWAYS executed (unless the handle wasn't successfully opened, of course).

    --
    Mats

  3. #3
    Registered User
    Join Date
    Jul 2007
    Posts
    6
    Thank you very much for your time.

    Yes, it seems, that dlbuff is being overwriting, but I`m calling dlbuff = g_new0 (gchar, 8192);
    in downloadstart_cb. And I`m calling it each time before new map will be downloaded. Or am I
    doing something wrong?

    Thanks for notice about dlsock, you are right.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by wingri View Post
    Thank you very much for your time.

    Yes, it seems, that dlbuff is being overwriting, but I`m calling dlbuff = g_new0 (gchar, 8192);
    in downloadstart_cb. And I`m calling it each time before new map will be downloaded. Or am I
    doing something wrong?

    Thanks for notice about dlsock, you are right.
    So are you FINISHED with the previous download when you call downloadstart_cb? If not, you're just overwriting the original value in dlbuff with a different one, which has two effects:

    - any code using dlbuff AFTER this, will write to the new dlbuff location.

    So if you start three downloads in short succession, the second and third ones will allocate new buffers, but the first one and the second one will write to the same buffer as the third download, which of course means that when you save the data, you only get ONE of the three maps - randomly choosen depending on which download "wins" (or, perhaps more likely, a mix of all three maps in some random combination).

    - you are not freeing the previous dlbuff, so you're "leaking memory".
    This will eventually cause your application to fail, unless the machine has "unlimited amount of memory". It is "sort of OK" to allow an application to leak small amounts of memory if you KNOW FOR SURE that it will finish soon after. But applications such as web-browsers, servers, editors, e-mail clients and such, that may be running for days or weeks without "quitting", it will definitely be a bad thing to leak ANY amount of memory.

    I would suggest that you use a structure of some sort to send to the download function, which contains all the relevant data for that particular download, including the buffer to use.

    I also think that you shouldn't necessarily keep an entire file in memory - unless you know for sure that the files are small, you can write out the part you got so far after you fetched some thousands of bytes. Yes, modern machines have large amounts of memory, but there's still no reason to just waste it for no particular good reason.

    --
    Mats

  5. #5
    Registered User
    Join Date
    Jul 2007
    Posts
    6
    Thank you, that`s true, i didn`t realize that. And thanks for the suggestion.
    I`ve made a new object:
    Code:
    typedef struct {
    	gchar *dlbuff;
    	gchar *dlpstart;
    	gint dlcount;
    	gchar writebuff[2000];
    	gint dldiff;
    } sendobject;
    and new array:
    Code:
    sendobject sendarray[20];
    and I`ve replaced writebuff with sendarray[mapyczcount].writebuff, dlbuff with sendarray[mapyczcount].dlbuff and so on.
    Now it downloads first five maps ok, while downloading the sixth map I`m getting error: Bad file descriptor.
    I`ve looked up this error in google, but I dindn`t find something relevant. I`m not sure, what it could mean.
    Writebuff seems to be ok.

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by wingri View Post
    Now it downloads first five maps ok, while downloading the sixth map I`m getting error: Bad file descriptor.
    I`ve looked up this error in google, but I dindn`t find something relevant. I`m not sure, what it could mean.
    Writebuff seems to be ok.
    Where do you get the error, and what is the value of the filedescriptor in question? Is it possible that you're getting some other error that leads to a file-descriptor being issued that isn't valid?

    By the way, wouldn't it be a good idea to stick the input/output file descriptors (or file-handles/file-pointers, whichever you are actually using) in the sendobject structure?

    I have a suspicion that you're closing a file and then trying to write to it after it's been closed, or that you can't actually open the file in the first place, and get a "bad" descriptor back.

    --
    Mats

  7. #7
    Registered User
    Join Date
    Jul 2007
    Posts
    6
    Error occures in downloadslave_cb here:
    Code:
    if (select (FD_SETSIZE, &readmask, NULL, NULL, &timeout) < 0)
    	{
    	    perror ("select() call");
    	}
    and also here:
    Code:
    if ((e = read (dlsock, tmpbuff, 8000)) < 0)
    			perror (_("read from Webserver"));
    The value of fd is '0';

    I`ve added gint fd; into sendobject and changed everywhere fd into sendarray[mapyczcount].fd, but there`s no change.
    Then I tried to open and close file descriptor in the downloadstart_cb (not in downloadslave_cb). But this didn`t seem to work. It downloaded pictures, but saved files were empty and error with file descriptor
    still occured.

    I have a suspicion that you're closing a file and then trying to write to it after it's been closed, or that you can't actually open the file in the first place, and get a "bad" descriptor back.
    That could be possible, but why it doesn`t occures while downloading the first file? It occures during downloading fourth or fifth file.

  8. #8
    Registered User
    Join Date
    Jul 2007
    Posts
    6
    Hi,
    I`m still trying to fix this error, but I`m not succesfull.

    Bad file description error still occures in downloadslave_cb while calling select function. After calling
    int sel = select (FD_SETSIZE, &sendarray[mapyczcount].readmask, NULL, NULL, &timeout);
    the value of sel is -1.

    Value of dlsock is 23, value of file descriptor is 0.
    sendarray[mapyczcount].writebuff seem like this: GET http://mapserver.mapy.cz/base/7_8200000_7e00000 HTTP/1.0
    User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
    Host: mapserver.mapy.cz
    Accept: */*
    Cookie: jscript=1

    After this, I`m getting also error in
    if ((e = read (dlsock, tmpbuff, 8000)) < 0)
    {
    perror (_("read from Webserver"));
    close (dlsock);
    }
    but I think it`s becasue of prevoius error.

    I`ve added also readmask into sendobject. Now it looks like this:

    Code:
    typedef struct {
    	gchar *dlbuff;
    	gchar *dlpstart;
    	gint dlcount;
    	gchar writebuff[2000];
    	gint dldiff;	
    	gint fd;
    	fd_set readmask;
    } sendobject;	
    sendobject sendarray[20];
    
    gint
    main_function(GtkWidget * widget, guint datum)
    {
    	mapyczcount = 0;
    
    	int j;
    	for (j = 0; j <= 19; j++)
    	{
    		while (gtk_events_pending ())
    				gtk_main_iteration ();
    
    		downloadstart_cb(widget, datum);
    	}
    }
    
    gint
    downloadstart_cb (GtkWidget * widget, guint datum)
    {
        struct sockaddr_in server;
        struct hostent *server_data;
        gchar str[100], sn[1000];
    
        downloadfilelen = 0;
        downloadactive = TRUE;
      
        while (gtk_events_pending ())
    	gtk_main_iteration ();
    
        /*  open socket to port80 */
        if ((dlsock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
        {
            perror (_("can't open socket for port 80"));
            return (FALSE);
        }
    
        server.sin_family = AF_INET;
        /*  We retrieve the IP address of the server from its name: */
        if (haveproxy)
    		g_strlcpy (sn, proxy, sizeof (sn));
        else
    	{
    	   g_strlcpy (sn, WEBSERVER, sizeof (sn));
    	}
    
        memcpy (&server.sin_addr, server_data->h_addr, server_data->h_length);
        server.sin_port = htons (proxyport);
       
        /*  We initiate the connection  */
        if (connect (dlsock, (struct sockaddr *) &server, sizeof server) < 0)
    	{
    	    perror (_("unable to connect to Website"));
    	    return (FALSE);
    	}
    
        write (dlsock, sendarray[mapyczcount].writebuff, strlen (sendarray[mapyczcount].writebuff));
        printf ("dlsock: %d, sendarray[mapyczcount].writebuff: %s\n", dlsock, sendarray[mapyczcount].writebuff);
    
    	sendarray[mapyczcount].dlbuff = g_new0 (gchar, 8192);
       	sendarray[mapyczcount].dlpstart = NULL;
    	sendarray[mapyczcount].dldiff = 0;
    	sendarray[mapyczcount].dlcount = 0;
    	
       	g_snprintf (str, sizeof (str),
    				_("Now connected to %s"), WEBSERVER); 
    	
    	gtk_timeout_add (100, (GtkFunction) downloadslave_cb, widget);
    
    	return TRUE;
    }
    
    gint
    downloadslave_cb (GtkWidget * widget, guint datum)
    {
        gchar tmpbuff[9000], str[100], *p;
        gint e;
        gchar nn[] = "\r\n\r\n";
        gdouble f;
        G_CONST_RETURN gchar *s;
        gchar s2 [50];
        
    	if (!downloadwindowactive ) 
    		return FALSE;
    
        FD_ZERO (&sendarray[mapyczcount].readmask);
        FD_SET (dlsock, &sendarray[mapyczcount].readmask);
        timeout.tv_sec = 0;
        timeout.tv_usec = 100000;
    
        int sel = select (FD_SETSIZE, &sendarray[mapyczcount].readmask, NULL, NULL, &timeout);
        if (sel < 0)
    	{
    		perror ("select() call");
    	}
    
        if (FD_ISSET (dlsock, &sendarray[mapyczcount].readmask))
    	{
    	    memset (tmpbuff, 0, 8192);
    	    if ((e = read (dlsock, tmpbuff, 8000)) < 0)
    		{
    			perror (_("read from Webserver"));
    			close (dlsock);
    		}
    
    	    if (e > 0)
    		{
    		    /*  in dlbuff we have all download data */
    			memcpy ((sendarray[mapyczcount].dlbuff + sendarray[mapyczcount].dlcount), tmpbuff, e);
    		    /*  in dlcount we have the number of download bytes */
    		    sendarray[mapyczcount].dlcount += e;
    		    /* now we try to get the filelength and begin of the gif image data */
    		    if (sendarray[mapyczcount].dlpstart == NULL)
    			{
    			    /*  CONTENT-LENGTH string should hopefully be in the first 4kB */
    			    memcpy (tmpbuff, sendarray[mapyczcount].dlbuff, 4096);
    			    /*  We make of this a null terminated string */
    			    tmpbuff[4096] = 0;
    			    g_strup (tmpbuff);
    			    p = strstr (tmpbuff, "CONTENT-LENGTH:");
    			    if (p != NULL)
    				{
    				    sscanf (p, "%s %d", str,
    					    	&downloadfilelen);
    				    /*  now we look for 2 cr/lf which is the end of the header */
    				    sendarray[mapyczcount].dlpstart = strstr (tmpbuff, nn);
    				    sendarray[mapyczcount].dldiff = sendarray[mapyczcount].dlpstart - tmpbuff + 4;
    				   
    				}
    			    else if (sendarray[mapyczcount].dlcount > 1000)
    				{
    				    /*  Seems there is no CONTENT-LENGTH field in expedia.com */
    				    sendarray[mapyczcount].dlpstart = strstr (tmpbuff, nn);
    				    sendarray[mapyczcount].dldiff = sendarray[mapyczcount].dlpstart - tmpbuff + 4;
    				    downloadfilelen = 200000;
    				    
    				}
    			}
    		    /*  Now we have the length and begin of the gif image data */
    		    if ((downloadfilelen != 0) && (sendarray[mapyczcount].dlpstart != NULL))
    			{
    				sendarray[mapyczcount].dlbuff = g_renew (gchar, sendarray[mapyczcount].dlbuff,
    								      sendarray[mapyczcount].dlcount + 8192);
    			    
    			    g_snprintf (str, sizeof (str),
    					_("Downloaded %d kBytes"),
    					(sendarray[mapyczcount].dlcount - sendarray[mapyczcount].dldiff) / 1024);
    			    
    			    while (gtk_events_pending ())
    				gtk_main_iteration ();
    			}
    
    		}
    	    if ((e == 0) || ((downloadfilelen + sendarray[mapyczcount].dldiff) == sendarray[mapyczcount].dlcount))
    		{
    
    		    if (downloadfilelen == 0)
    			g_snprintf (str, sizeof (str),
    				    _("Download FAILED!"));
    		    else
    			g_snprintf (str, sizeof (str),
    				    _("Download finished, got %dkB"),
    				    sendarray[mapyczcount].dlcount / 1024);
    		  
    		    close (dlsock);
    		    if (downloadfilelen != 0)
    			{
    			     s = gtk_entry_get_text (GTK_ENTRY (dltext));
    			    if (local_config.dir_home[strlen (local_config.dir_home) - 1] != '/')
    				g_strlcat (local_config.dir_home, "/",
    					   sizeof (local_config.dir_home));
    
    				g_strlcpy (downloadfilename, local_config.dir_home,
    					       sizeof (downloadfilename));
    
    				 g_snprintf (s2, sizeof (s2),
    				   			_("mapycz%d"), mapyczcount);
    				 g_strlcat (downloadfilename, s2,
    					       sizeof (downloadfilename));
    					
    				 sendarray[mapyczcount].fd = open (downloadfilename,
    						       O_RDWR | O_TRUNC | O_CREAT, 0644);
    				 if (sendarray[mapyczcount].fd < 1)
    				{
    				    perror (downloadfilename);
    				    gtk_timeout_add (3000,(GtkFunction) dlstatusaway_cb, widget);
    
    				    return FALSE;
    				}
    	
    				write (sendarray[mapyczcount].fd, sendarray[mapyczcount].dlbuff + sendarray[mapyczcount].dldiff, sendarray[mapyczcount].dlcount - 
    						sendarray[mapyczcount].dldiff);
    				close (sendarray[mapyczcount].fd);
    
    				if (mapyczcount == 19)
    				{
    					// save info about big picture
    				}
    				else
    					mapyczcount++;
    			}
    		    downloadwindowactive = FALSE;
    		    gtk_widget_destroy (downloadwindow);
    		    gtk_timeout_add (3000, (GtkFunction) dlstatusaway_cb, widget);
    
    		    return FALSE;
    		}
    	}
        else
    	{
    
    	    return TRUE;
    	}
    
    
        return TRUE;
    }
    Error still occures while downloading fourth or fifth picture. But the
    same error occures before as well. During downloading second or third
    picture I`m also getting bad file description error. But after that,
    I repeat calling procedure and picture is then downloaded succesfully

    Have you got any suggestion, please?

  9. #9
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,452
    > gchar tmpbuff[9000],
    > memset (tmpbuff, 0, 8192);
    > read (dlsock, tmpbuff, 8000)
    Some points.
    1. Some consistency in defining the size of buffer wouldn't go amiss here. With 3 different sizes, you're sure to screw it up at some point. Create a #define constant for this, and use it everywhere.
    2. the memset() is useless if you're using the return result of read() properly.

    There are several other places where similarly random numbers are plucked out of the air. Perhaps you've miss-guessed one of them.

    I notice that sendarray, mapyczcount, and dlsock (and probably some other things as well) seem to be global variables. One wonders at the chaos which results if two downloads start at the same time.

    > select (FD_SETSIZE, &sendarray[mapyczcount].readmask, NULL, NULL, &timeout);
    Using FD_SETSIZE is a cop-out.
    http://www.linuxmanpages.com/man2/select_tut.2.php

    Perhaps you should convince yourself that you can download all the files sequentially, before you start making it complicated by wrapping it up in this callback heavy GUI stuff.
    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.

  10. #10
    Registered User
    Join Date
    Jul 2007
    Posts
    6
    Now it works, thank you very much.

    The biggest problem was here:
    I notice that sendarray, mapyczcount, and dlsock (and probably some other things as well) seem to be global variables. One wonders at the chaos which results if two downloads start at the same time.
    Now, I`m sending mapyczcount as argument to downloadslave_cb.

  11. #11
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,452
    Once again, threads take another huge lump of flesh out of a programmer.
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 11-07-2005, 10:34 PM
  2. searching problem
    By DaMenge in forum C Programming
    Replies: 9
    Last Post: 09-12-2005, 01:04 AM
  3. half ADT (nested struct) problem...
    By CyC|OpS in forum C Programming
    Replies: 1
    Last Post: 10-26-2002, 08:37 AM
  4. binary tree problem - help needed
    By sanju in forum C Programming
    Replies: 4
    Last Post: 10-16-2002, 05:18 AM
  5. Program problem
    By Mick in forum C++ Programming
    Replies: 1
    Last Post: 02-26-2002, 06:41 AM

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