0

I am having a memory problem when executing this program, but I cannot solve it. The program is the client of a very simplified torrent made with TCP sockets. I can't quite understand where the error occurs. However, it depends on how you run it, it doesn't produce it. I have read answers to similar problems but I cannot replicate it to my case

How could I solve it?

        struct torrent_t Torrent_Client;
            struct sockaddr_in client_addr;
            unsigned int peer_count = 0;
            uint8_t buffer_enviar[RAW_MESSAGE_SIZE];
            char buffer_rebre[RAW_MESSAGE_SIZE];
            
            //Copy char* to another char*
            
            char* aux = (char*) malloc(strlen(argv[1]));
            
            printf("%s",aux);
            strcpy(aux,argv[1]);
        
            strtok(aux,".");
            printf("Nom fitxer %s",argv[1]);
            printf("Nom fitxer %s",aux);
        
        
            int create_torrent = create_torrent_from_metainfo_file(argv[1], &Torrent_Client, aux);
            
            if(create_torrent < 0){
            perror("Error al crear el torrent! :(");
            exit(EXIT_FAILURE);
        
            }
            //Socket
        
        int socket_client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //TCP!

        if(socket_client == -1){
            perror("Error al crear el socket! :(");
            exit(EXIT_FAILURE);
        }

        memset(&client_addr,0,sizeof(client_addr));


        client_addr.sin_family = AF_INET;

        //Direcció IP del socket.
        uint32_t direccion=0x0;
        direccion |= ((uint32_t) Torrent_Client.peers[peer_count].peer_address[3]);
        direccion = direccion << 8;
        direccion |= ((uint32_t) Torrent_Client.peers[peer_count].peer_address[2]);
        direccion = direccion << 8;
        direccion |= ((uint32_t) Torrent_Client.peers[peer_count].peer_address[1]);
        direccion = direccion << 8;

        direccion |= ((uint32_t) Torrent_Client.peers[peer_count].peer_address[0]);
        client_addr.sin_addr.s_addr = direccion;

        //Port del socket.

        client_addr.sin_port = Torrent_Client.peers[peer_count].peer_port;

        //Connect

        int connect_client = connect(socket_client, (const struct sockaddr*) &client_addr, sizeof(client_addr));

        if(connect_client < 0){
            perror("Error al fer el conect! :(");
            close(socket_client);
            exit(EXIT_FAILURE);
        }
            

        //Recorrem els blocs

        for(uint64_t bloc_number = 0; bloc_number < Torrent_Client.block_count; bloc_number++){

            //Variables:
            struct block_t bloque_rebut;
            
            memset(&buffer_enviar,0,sizeof(buffer_enviar));
            memset(&buffer_rebre,0,sizeof(buffer_rebre));

            for(int i = 0; i < 4; i++){
                buffer_enviar[i] = (uint8_t)(MAGIC_NUMBER >> 8*i);
            }
            buffer_enviar[4] = MSG_REQUEST;
            //buffer_enviar[5] = (uint8_t)(bloc_number);
            for(int i = 5; i < RAW_MESSAGE_SIZE-1; i++){
                buffer_enviar[i] = 0;
            }
            buffer_enviar[12] = (uint8_t)(bloc_number);

            printf("Enviar al bloc %li \n",bloc_number);

            ssize_t send_client = send(socket_client,buffer_enviar,sizeof(buffer_enviar),0);

            if(send_client < 0){
                perror("Error al fer al enviar el missatge! :(");
                //close(socket_client);
                exit(EXIT_FAILURE);
            }

            ssize_t recv_client = recv(socket_client,&buffer_rebre,sizeof(buffer_rebre),0);

            if(recv_client < 0){
                perror("Error al rebre el missatge! :(");
                //close(socket_client);
                exit(EXIT_FAILURE);
            }
            
            if (load_block(&Torrent_Client, 0, &bloque_rebut)) {
                        //perror("Error load"); 
                        //exit(EXIT_FAILURE); Estaria bé amb perror?
                        printf("Error load");
                        
            }uint64_t mida = get_block_size(&Torrent_Client, bloc_number);
            bloque_rebut.size = mida;
            //char buffer_bloc[mida];
            ssize_t recv_payload = recv(socket_client,&bloque_rebut,mida,0);



            if(recv_payload < 0){
                    perror("Error al rebre el payload! :(");
                    //close(socket_client);
                    exit(EXIT_FAILURE);
            }

            int guardar_bloc = store_block(&Torrent_Client, bloc_number, &bloque_rebut);
            printf("%li",bloc_number);
            
            if(guardar_bloc < 0){
                //close(socket_client);
                    perror("Error al guardar el bloc! :(");
            }   

        }
        
        printf("Ha funcionat correctament el torrent client");
        close(socket_client);
        
        return 0;
        }

I have updated the line char* aux = (char*) malloc(strlen(argv[1])); to char* aux = (char*) malloc(strlen(argv[1])+1); and I removed printf("%s",aux);

  • 2
    What is the problem ? What do you see ? What do you expect to see ? – aureliar Apr 19 '21 at 15:10
  • 2
    `char* aux = (char*) malloc(strlen(argv[1])); printf("%s",aux); strcpy(aux,argv[1]);` is bad because 1. Value of buffer allocated via `malloc()` and not initialized is used. The value is indeterminate and using that invokes *undefined behavior*. 2. The `strcpy()` will cause out-of-range access. One more element for teminating null-character is required. 3. `malloc()` may return `NULL`, but the result is not checked. 4. Casting results of `malloc()` is [considered as a bad practice](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – MikeCAT Apr 19 '21 at 15:10
  • I understand the problem, but how could I solve it in this case? @MikeCAT – Desiree Pasion Rodriguez Sanch Apr 19 '21 at 15:21
  • 1
    Firstly have `malloc()` allocate one more element for terminating null-character. How to fix `printf("%s",aux);` will depend what you want to do. – MikeCAT Apr 19 '21 at 15:22
  • 1
    Okay, done. I have also commented printf("%s",aux); now aux only used in strcpy and strotok @MikeCAT – Desiree Pasion Rodriguez Sanch Apr 19 '21 at 15:31
  • However, despite the changes, the same thing continues to occur @MikeCAT – Desiree Pasion Rodriguez Sanch Apr 19 '21 at 16:13
  • @aureliar in valgrind i have this problem Address 0x0 is not stack'd, malloc'd or (recently) free'd – Desiree Pasion Rodriguez Sanch Apr 19 '21 at 17:25
  • @MikeCAT in valgrind i have this problem Address 0x0 is not stack'd, malloc'd or (recently) free'd – Desiree Pasion Rodriguez Sanch Apr 19 '21 at 17:25
  • Ok, will your design/code still work if every send() and every recv() call returns 1 if successful, ie. only one byte loaded into the passed buffer from the TCP stream? – Martin James Apr 19 '21 at 17:31
  • @MartinJames yes until finished – Desiree Pasion Rodriguez Sanch Apr 19 '21 at 17:42
  • @DesireePasionRodriguezSanch Would you be able to run [`ASAN`](https://github.com/google/sanitizers/wiki/AddressSanitizer) on your code? Compile your code with debug information (`-g` flag for CLANG and GCC) and it should help figure out the issue. – Zoso Apr 19 '21 at 22:20

0 Answers0