Проблемы с записью функции memset

Я пишу функцию memset и мой код ниже, у меня проблема

void* memsetFun(void* pointer, int c, int size) {

  if ( pointer != NULL && size > 0 ) {

    unsigned char* pChar =  pointer;


    int i = 0;

      for ( i = 0; i < size; ++i) {

      unsigned char temp = (unsigned char) c;

      *pChar++ = temp; // or pChar[i] = temp (they both don't work)

    }
  }  
    return pointer;


}

Я также пробовал pChar [i] = значение, которое мы хотим и все еще не работаем. Это дает мне некоторые номера мусора, которые не имеют никакого смысла.

И я называю это:

memsetFun(address, num, size);
printf("value at %p is %d\n", address, *((int*) address));

Когда я вызываю адрес (я просто вводим адрес)

Например, если вы печатаете символы (c), он печатает как странный char, который выглядит как (для значения 4)

0 0
0 4

Ответ 1

Ваш код выглядит хорошо для меня, и несколько человек здесь прокомментировали, что он работает в их системе.

Итак, очевидно, что нужно отлаживать его - это умение, которое пригодится совсем немного в будущем:-) Вы должны изучить его сейчас.

Что выводит следующий код при его запуске?

void* memsetFun(void* pointer, int c, int size) {
    printf("A %x %d %d\n", pointer, c, size);
    if ( pointer != NULL && size > 0 ) {
        printf("B\n");
        unsigned char* pChar =  pointer;
        int i = 0;
        for ( i = 0; i < size; ++i) {
            printf("C %d (%d)", i, *pChar);
            unsigned char temp = (unsigned char) c;
            *pChar++ = temp; // or pChar[i] = temp (they both don't work)
            printf(" -> (%d)", i, *(pChar-1));
        }
    }  
    printf("D\n");
    return pointer;
}

На выходе должно быть понятно, какие пути использует код и каковы ваши параметры (что значительно облегчит процесс отладки).

Update:

Если вы заполняете свой блок памяти чем-то другим, кроме нулей, и используя это:

printf("value at %p is %d\n", address, *((int*) address));

чтобы распечатать его, вы получите странные результаты.

В основном вы запрашиваете, чтобы количество этих байтов интерпретировалось как целое. Так, например, если вы заполнили его байтами 0x02 и у вас есть 4-байтовый целочисленный тип, вы получите целое число 0x02020202 (33686018), а не 0x02, как вы можете ожидать. Если вы хотите увидеть, что такое первое значение символа, используйте:

printf("value at %p is %d\n", address, *((char*) address));

И на основе вашего последнего обновления вопроса:

Например, если вы печатаете символы (c), он печатает как странный char, который выглядит как (для значения 4)
0 0
0 4

Если это один символ, и вы печатаете его как персонажа, вероятно, нет ничего плохого. Многие выходные потоки дадут вам это для контрольного символа (CTRL-D в этом случае, ASCII-код 4). Если вы вместо этого заполнили его кодом ASCII 0x30 (48), вы увидите, что символ "0" или ASCII 0x41 (65) даст вам "A".

Ответ 2

Как уже указывалось, ваша функция работает так, как должна. Вот полный пример:

#include <assert.h>
#include <string.h>

void* memsetFun(void* pointer, int c, int size) {
    if ( pointer != NULL && size > 0 ) {
        unsigned char* pChar =  pointer;
        int i = 0;
        for ( i = 0; i < size; ++i) {
            unsigned char temp = (unsigned char) c;
            *pChar++ = temp; // or pChar[i] = temp (they both don't work)
        }
    }
    return pointer;
}

int main() {
    // Your memset
    char a[10];
    memsetFun(a, 'A', sizeof(a));

    // Uses system memset for verification
    char b[10];
    memset(b, 'A', sizeof(b));

    assert(sizeof(a) == sizeof(b));
    assert(memcmp(a, b, sizeof(b)) == 0);
    return 0;
}

Ответ 3

return p; предотвращает это от компиляции: p не определен.

Небольшая проблема эффективности - на практике это малоэффективно, так как любой хороший компилятор изменил бы ее, но перфекционисты кодирования не позволили бы ему оставаться - назначение temp находится внутри цикла, но это одно и то же задание каждый раз. То есть, назначение temp может быть перемещено до цикла.

Ответ 4

Вы возвращаете p, который не определен/не указывает на что-либо в частности. Может быть, вы имели в виду pointer?

Ответ 5

Код логически корректен. При изменении p = > pointer он работает правильно.

Уточнить, как именно "не работает". Возможно, вы не понимаете, что он должен делать?

Ответ 6

Вероятно, вы получаете номера мусора, потому что вы выполняете от int (4 байта) до unsigned char (1 байт), поэтому, если c > 255 или < 0 вы не будете измерять значения, которые вы ожидаете.

Ответ 7

Ваша функция как есть работает для меня.

Я полагаю, вы называете это неправильным. Я называю это следующим образом

char a[100];
memsetFun(a, 0, sizeof a);
int b[100];
memsetFun(b, 0, sizeof b);

Как вы называете свой memsetFun()?

Изменить

С

int b[100];
memsetFun(b, 9, sizeof b);

поскольку int состоит из 4 байтов (в моей системе), каждое значение будет установлено на 0x09090909 или 151587081.

Ответ 8

Я проверил тест, если ваша программа установила память для вектора int из 5 элементов, задав значение 0x01.

Проблема заключается в том, что вы выполняете итерацию в векторе int (например, 4 байта), но повторяете его с помощью арифметики указателя char (1 байт). Если вы хотите memset 0x01, например, вы будете записывать этот номер на одно значение в векторе: 00000001000000010000000100000001 который дает мне то же значение, что и исходный memset.

Ответ 9

Это именно то, что он должен был делать. Ваша функция работает отлично. Значение "0x4" не является символом ASCII "4".