C char** Pointer

Ne kadar doğru veya yanlış bir çözüm bilmiyorum ama allocate edilen değişkenin içindeki değeri silmek için şöyle bir şey yaptım:

#include <stdio.h>
#include <windows.h>
#include <winhttp.h>
#include <stdlib.h>
#include <string.h>
#include "types.h"


INTERNET_RESPONSE send_request(wchar_t* domain, wchar_t* url, int timeout, BOOL SSLVerify){
    INTERNET_RESPONSE return_request;

    HINTERNET winhttp = WinHttpOpen(L"Updater", WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);

    if(!winhttp){
        return_request.api_code = GetLastError();
        return_request.server_status_code = 0;
        return_request.data = "";
        return return_request;
    }

    HINTERNET server_connection = WinHttpConnect(winhttp, domain, INTERNET_DEFAULT_PORT, 0);

    if(!server_connection){
        return_request.api_code = GetLastError();
        return_request.server_status_code = 0;
        return_request.data = "";
        return return_request;
    }

    HINTERNET server_request = WinHttpOpenRequest(server_connection, L"GET", url, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0);

    if(!server_request){
        return_request.api_code = GetLastError();
        return_request.server_status_code = 0;
        return_request.data = "";
        return return_request;
    }

    BOOL set_timeout = WinHttpSetTimeouts(server_request, timeout*1000, timeout*1000, timeout*1000, timeout*1000);

    if(!set_timeout){
        return_request.api_code = GetLastError();
        return_request.server_status_code = 0;
        return_request.data = "";
        return return_request;
    }


    BOOL request_response = WinHttpSendRequest(server_request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0);

    if(!request_response){
        return_request.api_code = GetLastError();
        return_request.server_status_code = 0;
        return_request.data = "";
        return return_request;
    }

    request_response = WinHttpReceiveResponse(server_request, NULL);

    if(!request_response){
        return_request.api_code = GetLastError();
        return_request.server_status_code = 0;
        return_request.data = "";
        return return_request;
    }

    long unsigned int status_code = 0;
    long unsigned int status_code_size = sizeof(status_code);

    BOOL query_status_code = WinHttpQueryHeaders(server_request, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, &status_code, &status_code_size, WINHTTP_NO_HEADER_INDEX);

    if(!query_status_code){
        return_request.api_code = GetLastError();
        return_request.server_status_code = 0;
        return_request.data = "";
        return return_request;
    }

    unsigned long int data_size = 0;   

    return_request.data = (char *)calloc(0, sizeof(char));

    printf("Allocated variable length: %d\n",strlen(return_request.data));

    do{
        BOOL get_available_data_size = WinHttpQueryDataAvailable(server_request, &data_size);

        if(!data_size){
            break;
        }
        
        if(!get_available_data_size){
            return_request.api_code = GetLastError();
            return_request.server_status_code = 0;
            return_request.data = "";
            return return_request;
        }

        return_request.data = realloc(return_request.data, (strlen(return_request.data)+data_size+1)*sizeof(char));

        memset(&return_request.data[strlen(return_request.data)], 0, (data_size+1)*sizeof(char));
            
        BOOL read_data = WinHttpReadData(server_request, &return_request.data[strlen(return_request.data)], data_size, &data_size);

        //memcpy(return_request.data, data, data_size+1);

        if(!read_data){
            return_request.api_code = GetLastError();
            return_request.server_status_code = 0;
            return_request.data = "";
            return return_request;
        }

    }while(data_size > 0);

    return_request.api_code = 0;
    return_request.server_status_code = status_code;

    WinHttpCloseHandle(server_request);
    WinHttpCloseHandle(server_connection);
    WinHttpCloseHandle(winhttp);

    return return_request;


}

malloc(0) yanlis degil fakat dondurdugu 0 byte’lik yerden herhangi bir sey okumak UB. printf 0 bulana kadar byte okuyor.


Raw hafiza alanlariyla calisirken string fonksiyonlarindan ziyade pointer + size ciftiyle calismak lazim.

Tam olarak anlamadım, yanlış yahut standartlara aykırı bir şey mi yaptım? Peki aykırıysa kod başka sistemlerde de stabil olur mu? Bu arada yardımlarınız için size ve @semtex’e çok teşekkür ederim, birçok yeni şey öğrettiniz.

Merhabalar, hem null terminator içeren binary içerikler hem de normal metinlerin içeriğini alabilmek için kodu şöyle düzenledim:

#include <stdio.h>

#include <windows.h>
#include <winhttp.h>
#include <stdlib.h>
#include <string.h>
#include "types.h"


INTERNET_RESPONSE send_request(wchar_t* domain, wchar_t* url, int timeout, BOOL SSLVerify){
    INTERNET_RESPONSE return_request;

    HINTERNET winhttp = WinHttpOpen(L"Mozilla/5.0", WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);

    if(!winhttp){
        return_request.api_code = GetLastError();
        return_request.server_status_code = 0;
        return_request.data = "";
        return_request.data_size = 0;
        return return_request;
    }

    HINTERNET server_connection = WinHttpConnect(winhttp, domain, INTERNET_DEFAULT_PORT, 0);

    if(!server_connection){
        return_request.api_code = GetLastError();
        return_request.server_status_code = 0;
        return_request.data = "";
        return_request.data_size = 0;
        return return_request;
    }

    const WCHAR* content_types[3] = {L"text/*", L"application/*", NULL};

    HINTERNET server_request = WinHttpOpenRequest(server_connection, L"GET", url, NULL, WINHTTP_NO_REFERER, content_types, 0);

    if(!server_request){
        return_request.api_code = GetLastError();
        return_request.server_status_code = 0;
        return_request.data = "";
        return_request.data_size = 0;
        return return_request;
    }

    BOOL set_timeout = WinHttpSetTimeouts(server_request, timeout*1000, timeout*1000, timeout*1000, timeout*1000);

    if(!set_timeout){
        return_request.api_code = GetLastError();
        return_request.server_status_code = 0;
        return_request.data = "";
        return_request.data_size = 0;
        return return_request;
    }


    BOOL request_response = WinHttpSendRequest(server_request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0);

    if(!request_response){
        return_request.api_code = GetLastError();
        return_request.server_status_code = 0;
        return_request.data = "";
        return_request.data_size = 0;
        return return_request;
    }

    request_response = WinHttpReceiveResponse(server_request, NULL);

    if(!request_response){
        return_request.api_code = GetLastError();
        return_request.server_status_code = 0;
        return_request.data = "";
        return_request.data_size = 0;
        return return_request;
    }

    long unsigned int status_code = 0;
    long unsigned int status_code_size = sizeof(status_code);

    BOOL query_status_code = WinHttpQueryHeaders(server_request, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, &status_code, &status_code_size, WINHTTP_NO_HEADER_INDEX);

    if(!query_status_code){
        return_request.api_code = GetLastError();
        return_request.server_status_code = 0;
        return_request.data = "";
        return return_request;
    }

    unsigned long int buffer_data_size = 0;
    unsigned long int allocated_data_size = 0;

    return_request.data = (char *)calloc(0, sizeof(char));

    do{

        BOOL get_available_data_size = WinHttpQueryDataAvailable(server_request, &buffer_data_size);

        //printf("Buffer data size: %d\n", allocated_data_size);

        if(!get_available_data_size){
            //printf("Res: %d\n", GetLastError());

            return_request.api_code = GetLastError();
            return_request.server_status_code = 0;
            return_request.data = "";
            return_request.data_size = 0;
            return return_request;
        }

        if(!buffer_data_size){
            //printf("Data ended!\n");
            break;
        }
        
        //printf("New buffer size: %d\n", allocated_data_size+data_size+1);

        return_request.data = realloc(return_request.data, (allocated_data_size+buffer_data_size+1));

        memset(&return_request.data[allocated_data_size], 0, (buffer_data_size+1));
            
        BOOL read_data = WinHttpReadData(server_request, &return_request.data[allocated_data_size], buffer_data_size, NULL);

        //memcpy(return_request.data, data, data_size+1);

        allocated_data_size += buffer_data_size;

        if(!read_data){
            return_request.api_code = GetLastError();
            return_request.server_status_code = 0;
            return_request.data = "";
            return_request.data_size = 0;
            return return_request;
        }

    }while(buffer_data_size > 0);

    //printf("Read bytes is: %d\n", read_bytes);

    return_request.api_code = 0;
    return_request.server_status_code = status_code;
    return_request.data_size = allocated_data_size;

    WinHttpCloseHandle(server_request);
    WinHttpCloseHandle(server_connection);
    WinHttpCloseHandle(winhttp);

    return return_request;


}

Kodu kendim denediğimde sıkıntısız istediğim dosyaları indirebiliyorum. Eğer kodda hata varsa belirtirseniz müteşekkir olurum.