Doubts regarding the use of the memset and memcpy functions

2

I've been crawling some codes on the internet and at a certain point I ended up with the functions memset and memcpy . I was able to understand superficially the functions of the mentioned functions, since all sources that provide some information or example code in relation to these two functions were somewhat similar and had enough basic information. However, I ended up asking the following questions:

  • Is it wrong to use memcpy and memset with non-char data?
  • What is the utility of the void pointer returned by the memset function?
  • What is the utility of the void pointer returned by the memcpy function?
  • Does memcpy only copy the data or does it also copy the address of the copied block?

Example:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SIZE 10
#define NEW_SIZE 20

int main(void){

    int *numbers=(int*)calloc(SIZE, sizeof(int));

    for(unsigned int i=0; i<SIZE; i++){

        numbers[i]=i+1;
    }

    for(unsigned int i=0; i<SIZE; i++){

        printf("numbers[%d]=%d\n", i, numbers[i]);
    }

    printf("\n==================\n\n");

    int *aux=(int*)realloc(numbers, NEW_SIZE*sizeof(int));

    if(aux!=NULL){

        memcpy(numbers, aux, NEW_SIZE*sizeof(int)); //isso é a mesma coisa que 'numbers=aux;' ???

        for(unsigned int i=SIZE; i<NEW_SIZE; i++){

            numbers[i]=i+1;
        }

        for(unsigned int i=0; i<NEW_SIZE; i++){

            printf("numbers[%d]=%d\n", i, numbers[i]);
        }
    }

    free(numbers);

    return 0;
}
    
asked by anonymous 04.05.2018 / 05:50

1 answer

2
  

Is it wrong to use memcpy and memset with data not char ?

  • memcpy can be applied to any type
  • memset is in fact wrong with something other than char . In that case it will not give the desired result, since the value is assigned byte to byte and interpreted as unsigned char .

    From documentation :

      

    (...) specified value (interpreted as an unsigned char).

    But it is relatively easy to demonstrate that it goes wrong when used with other types. Consider the following example, which tries to assign the value 5 to two houses of an integer array with memset :

    int arr[2];
    memset(arr, 5, sizeof(int) * 2);
    printf("%d %d", arr[0], arr[1]);
    

    Here you might be thinking that the result would be 5 5 when in fact it is:

    84215045 84215045
    

    See it on Ideone

    But how did that result come about?

    It turns out that memset assigned 5 to each byte of the two integers. Then one of these integers in its representation in the memory looks like this:

    -----------------
    | 5 | 5 | 5 | 5 |
    -----------------
    

    That expanded to binary would look like this:

    ---------------------------------------------
    | 00000101 | 00000101 | 00000101 | 00000101 |
    ---------------------------------------------
    

    What form the value 00000101000001010000010100000101 in binary, corresponding to 84215045 .

    When it was meant to be that way

    -----------------
    |       5       |
    -----------------
    

    That expanding to binary would already look like this (assuming the little-endian format):

    ---------------------------------------------
    | 00000000 | 00000000 | 00000000 | 00000101 |
    ---------------------------------------------
    

    This is the problem of using different types in memset . Curiously if I wanted to assign 0 would work correctly, because 0 is always 0 regardless of the amount of bits we are considering.

  

How useful is the pointer of type void returned by the function memset ?

Very little use has this pointer, but you can for example chain functions calls:

strcpy(memset(ptr, 0, 200), "texto");

Something that would not be possible if the return type was void . Yet it is a very particular and certainly unusual case.

  

How useful is the pointer of type void returned by the function memcpy ?

Same answer as the previous question, chaining calls.

  

Does memcpy only copy the data or does it also copy the address of the copied block?

memcpy copies only the data that is in the address passed as the second parameter, called source , to the destination pointer named destination .

    
04.05.2018 / 12:09