Im developing a C code to do a GET request and handle variable size response.
I use realloc to resize the heap chunk where i am storing the response. The problem is that i am getting an error related with the CrtIsValidHeapPointer function of the realloc call.
The loop is working during 6 times but it is throwing up an error at the 7th loop. I have here the code for you:
#include "stdafx.h"
using namespace std;
int GET_request(char *hostname, char *path);
char *scat(char *, char *);
int _tmain(int argc, _TCHAR* argv[])
{
GET_request("www.marca.com", "/");
}
int GET_request(char *hostname, char *path){
char request[256];
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("WSAStartup failed.\n");
system("pause");
return 1;
}
SOCKET Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct hostent *host;
host = gethostbyname(hostname);
SOCKADDR_IN SockAddr;
SockAddr.sin_port = htons(80);
SockAddr.sin_family = AF_INET;
SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr);
printf("Connecting...\n");
if (connect(Socket, (SOCKADDR*)(&SockAddr), sizeof(SockAddr)) != 0){
printf("Could not connect");
system("pause");
return 1;
}
printf("Connected.\n");
if ((strlen(hostname) + strlen(path)) > 197)
{
printf("Lenght too long for a GET path");
return 1;
}
else
{
const char *method = "GET ";
strcpy_s(request, method);
strcat_s(request, path);
strcat_s(request, " HTTP/1.1\r\n");
strcat_s(request, "Host: ");
strcat_s(request, hostname);
strcat_s(request, "\r\n");
strcat_s(request, "Connection: close\r\n\r\n");
}
//printf_s(request);
int len;
len = strlen(request);
system("pause");
send(Socket, request, strlen(request), 0);
char *ptr = (char*)calloc(sizeof(char),1024);
char *ptr2 = NULL;
int nDataLength;
int i = 0;
while ((nDataLength = recv(Socket, ptr, 1023, 0)) > 0){
if (i > 0){//prepare in case that the response is bigger than 1024 bytes
//printf("Data len: %d\n", nDataLength);
//system("pause");
printf("%p apunta a %d len: %d e i vale: %d\n", ptr2, *ptr2, ((1023 * i) + nDataLength), i);
system("pause");
ptr2 = (char*)realloc(ptr2, ((1023 * i) + nDataLength));
if (ptr2==NULL){
printf("Some error reallocating memory\n");
system("pause");
i++;
}
else{
memcpy(ptr2 + (1024 * i), ptr, nDataLength);
//printf("%s\n", ptr2);
//system("pause");
i++;
}
}
else{
ptr2 = (char*)realloc(ptr2, ((1023 * i) + nDataLength));
memcpy(ptr2, ptr, nDataLength);
i++;
}
}
printf("%s",ptr2);
system("pause");
closesocket(Socket);
WSACleanup();
system("pause");
FILE* pFile;
pFile = fopen("myfile.txt", "wb");
fwrite(ptr2, 1, strlen(ptr2), pFile);
fclose(pFile);
free(ptr2);
return 0;
}
You can just check the while
loop. I just wanted to give you all the code in case that you want to try it.
Im getting this:
Connecting...
Connected.
Press any key to continue . . .
0033D500 apunta a 72 len: 2046 e i vale: 1
Press any key to continue . . .
0033D500 apunta a 72 len: 3069 e i vale: 2
Press any key to continue . . .
0033D500 apunta a 72 len: 4092 e i vale: 3
Press any key to continue . . .
0033D500 apunta a 72 len: 5115 e i vale: 4
Press any key to continue . . .
0033D500 apunta a 72 len: 6138 e i vale: 5
Press any key to continue . . .
0033D500 apunta a 72 len: 7161 e i vale: 6
Press any key to continue . . .
Thanks
You are allocating with
ptr2 = (char*)realloc(ptr2, ((1023 * i) + nDataLength));
using 1023*i
, but in copy doing
memcpy(ptr2 + (1024 * i), ptr, nDataLength);
i.e. using 1024*i
So you are writing to more than you allocated. Referring to unallocated memory is undefined behavior and most likely cause fatal error at some point.