1

Got a huge problem. Let's say, that I have pointer to a large string (~1500 characters) and I want to print it. What I get in the result is only a part of that string. After the program prints that part it asks me for a newline. After I press enter the program prints the rest of the string and terminates. It happens when I try to run my program in terminal or with IDE. If I try to debug it, it works perfectly. I need it to print whole string without terminating the program. So, here's the code (there's lots of mistakes in the code):

#include<stdio.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netdb.h>
#include<string.h>

#define SOCKET int        // Apibreziame sinonima 'int' tipui, kad butu
                          // unix ir WIN sistemoms bendras kodas dirbant
                          // su soketu deskriptoriais.
#define closesocket close // Apibreziame sinonima close () funkcijai
                          // closesocket (), kuris yra analogas Windows
                          // tipo sistemose. Tai del kodo suvienodinimo.
#define INVALID_SOCKET -1 // Apibreziame del kodo suvienodinimo, klaidos
#define SOCKET_ERROR -1   // situacijai nusakyti konstantas, kurios WINSOCK'o

#define MAX_CH 255
#define POP3_PORT 110
#define MAXLEN 1024

int main()
{
    SOCKET socketE;
    struct sockaddr_in servaddr;
    struct hostent* h = NULL;

    char* Packet = NULL;

    Packet = (char*)malloc(MAX_CH);
    memset(Packet, 0, sizeof(Packet));

    printf("POP3 server: ");
    gets(Packet);

    /*******{ 
    client connects to the mail server and other stuff
    server sends greeting message
    client receives greeting message 
    }*******/

    if (!strstr(Packet,"+OK")) {
        print_error(Packet);
    }
    else {
        printf("%s", Packet);
        int printedData = 0;
        while (1) {
            Packet = (char*)realloc(NULL, 1);
            memset(Packet, 0, sizeof(Packet));
            gets(Packet);
            strcat(Packet, "\n");
            if (SOCKET_ERROR == SendPacket(&socketE, Packet)) {
                print_error("Error on sending data to mail server.\n");
            }
            memset(Packet, '\0', sizeof(Packet));
            if (SOCKET_ERROR == ReceivePacket(&socketE, &Packet)) {
                print_error("Error on receiving data from mail server.\n");
            }
            if (!strstr(Packet,"+OK")) {
                fwrite(Packet, 1, strlen(Packet), stdout);
                break;
            }
            printf("%s", Packet);  //THIS IS WHERE THE PRINT PART COMES
        }
    }
    close(socketE);
    return 0;
}

Okey, so I have found out that this if clause (I mean, even if this if is false) stops program from printing all the content. If I remove/comment it, I got my program working correctly. Is it possible, that this one causes all the problems?

if (!strstr(Packet,"+OK")) {
    fwrite(Packet, 1, strlen(Packet), stdout);
    break;
}
trimpirim
  • 71
  • 1
  • 7
  • Welcome to stackoverflow.com. Please take some time to read the [FAQ](http://stackoverflow.com/faq), especially the part about how to ask questions. I also recommend you to read http://sscce.org/ and http://www.whathaveyoutried.com/ as those texts will help you create better questions to post here. – Some programmer dude Nov 21 '12 at 07:11

3 Answers3

2

This:

Packet = (char*)realloc(NULL, 1);
memset(Packet, 0, sizeof(Packet));

causes undefined behavior. It allocates a single byte (why would you ever do this?) and then clears sizeof(Packet) bytes, which on most typical systems today is either 4 or 8 bytes. Thus, it writes outside the allocated memory. Note that sizeof cannot track dynamic allocations, so this whole pattern is wrong.

Also, please note that dynamic memory allocation can fail; you must check the return value of every call to realloc() before relying on the returned pointer being valid. If it's NULL, you can't access through it.

Further, just like with malloc(), please don't cast the return value of realloc() in C.

Community
  • 1
  • 1
unwind
  • 391,730
  • 64
  • 469
  • 606
  • Not to mention that `ReceivePacket()` isn't told how big the buffer it's reading data into is (it probably assumes that the buffer is `MAXLEN` in size). – Michael Burr Nov 21 '12 at 08:04
  • Let's say that I have fixed these mistakes. Still I can't get all the data printed. Any other solutions? – trimpirim Nov 21 '12 at 10:43
  • @trimprim: Have you looked at what's in the buffer using a debugger? Are there null characters in there? It's hard to guess at what might be wrong when we'd be guessing at the code's state. – Michael Burr Nov 21 '12 at 19:36
  • Yep, I guess so, because after receiving part of packet and placing it into a pointer of characters, I memset whole buffer with '\0' – trimpirim Nov 22 '12 at 11:50
0

Try to add flush after printf:

printf("%s", Packet);
fflush(stdout);

printf use stdout, which is line buffered. So printf texts can be partly flushed (printed) if there is no '\n' in the end of the string.

In your case unflushed text is flushed when you type the newline.

SKi
  • 8,007
  • 2
  • 26
  • 57
  • I have tried it already. It seems, that bigger part of string got printed then it was before, yet it asks me for newline symbol. – trimpirim Nov 21 '12 at 07:11
0

Stdout is line buffered and characters in the stdout stream are saved until a newline is output or input is read from any stream attached to a terminal device, or if the stream buffer gets full. so you may either put the '\n' character in your printf like printf("%s\n",Packet); or just disable the stdout buffering using setbuf(stdout, NULL); for printf to print the complete string

Muhammad Usama
  • 2,797
  • 1
  • 17
  • 14