Подтвердить что ты не робот

Использование memset для целочисленного массива в c

char str[]="beautiful earth";
memset(str,'*',6);
printf("%s",str);

output:
******ful earth

1) Как и при использовании memset, мы можем инициализировать только несколько значений индекса целочисленного массива до 1, как указано ниже.

int arr[15];
memset(arr,1,6);
4b9b3361

Ответ 1

Нет, вы не можете использовать memset() как это. Справочная страница говорит (выделение мое):

Функция memset() заполняет первые n байтов области памяти, на которую указывает s постоянным байтом c.

Так как int обычно составляет 4 байта, это не обрезает его.


Если вы (неправильно !!) попытаетесь сделать это:

int arr[15];
memset(arr, 1, 6*sizeof(int));    //wrong!

тогда первые 6 int в массиве будут фактически установлены в 0x01010101 = 16843009.

Единственный раз, когда действительно приемлемо записывать "блоб" данных с небайтовым типом данных, это memset(thing, 0, sizeof(thing)); "обнулить" всю структуру/массив. Это работает, потому что NULL, 0x00000000, 0.0, все полностью нули.


Решение состоит в том, чтобы использовать цикл for и установить его самостоятельно:

int arr[15];
int i;

for (i=0; i<6; ++i)    // Set the first 6 elements in the array
    arr[i] = 1;        // to the value 1.

Ответ 2

Короткий ответ, НЕТ.

Длинный ответ, memset устанавливает байты и работает для символов, поскольку они являются одиночными байтами, но целые числа не являются.

Ответ 3

Третий аргумент memset - размер байта. Таким образом, вы должны установить общий размер байта arr[15]

memset(arr, 1, sizeof(arr));

Однако, вероятно, вам нужно установить значение 1 для целых элементов в обр. Тогда вам лучше установить в цикле.

for (i = 0; i < sizeof(arr)/sizeof(arr[0]); i++) {
    arr[i] = 1;
}

Потому что memset() устанавливает 1 в каждом байте. Так что это не ваш ожидаемый.

Ответ 4

В Linux, OSX и других UNIX-подобных операционных системах, где wchar_t - 32 бита, и вы можете использовать wmemset() вместо memset().

#include<wchar.h>
...
int arr[15];
wmemset( arr, 1, 6 );

Обратите внимание, что wchar_t в MS-Windows - 16 бит, поэтому этот трюк может не работать.

Ответ 5

Нет, вы не можете [переносить] использовать memset для этой цели, если желаемое целевое значение не равно 0. memset рассматривает область целевой памяти как массив байтов, а не массив int s.

Довольно популярный взлом для заполнения области памяти повторяющимся шаблоном основан на memcpy. Критически полагается на ожидание того, что memcpy копирует данные в прямом направлении

int arr[15];

arr[0] = 1;
memcpy(&arr[1], &arr[0], sizeof arr - sizeof *arr);

Это, конечно, довольно уродливый взлом, поскольку поведение стандартного memcpy составляет undefined, когда области памяти источника и места назначения перекрываются. Вы можете написать свою собственную версию memcpy, хотя, чтобы убедиться, что она копирует данные в прямом направлении и использует это выше. Но это не стоит того. Просто используйте простой цикл, чтобы установить элементы вашего массива в нужное значение.

Ответ 6

Так как никто не упоминал об этом...

Хотя вы не можете инициализировать целые числа со значением 1, используя memset, вы можете инициализировать их со значением -1 и просто измените свою логику для работы с отрицательными значениями.

Например, чтобы инициализировать первые 6 номеров вашего массива с помощью -1, вы сделали бы

memset(arr,-1,6*(sizeof int));

Кроме того, если вам нужно выполнить эту инициализацию только один раз, вы можете фактически объявить массив, начинающийся со значений 1 из времени компиляции.

int arr[15] = {1,1,1,1,1,1};

Ответ 7

Memset устанавливает значения для типов данных, имеющих 1 байт, но целые числа имеют 4 байта или более, поэтому он не будет работать, и вы получите значения мусора. Он в основном используется, когда вы работаете с char и строковыми типами.

Ответ 8

Я попробовал следующую программу, и кажется, что вы можете инициализировать ваш массив, используя memset() только с -1 и 0

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

void printArray(int arr[], int len)
{
        int i=0;
    for(i=0; i<len; i++)
    {
        printf("%d ", arr[i]);
    }
    puts("");
}

int main()
{
    int arrLen = 15;
    int totalNoOfElementsToBeInitialized = 6;

    int arr[arrLen];
    printArray(arr, arrLen);
    memset(arr, -1, totalNoOfElementsToBeInitialized*sizeof(arr[0]));
    printArray(arr, arrLen);
    memset(arr, 0, totalNoOfElementsToBeInitialized*sizeof(arr[0]));
    printArray(arr, arrLen);
    memset(arr, 1, totalNoOfElementsToBeInitialized*sizeof(arr[0]));
    printArray(arr, arrLen);
    memset(arr, 2, totalNoOfElementsToBeInitialized*sizeof(arr[0]));
    printArray(arr, arrLen);
    memset(arr, -2, totalNoOfElementsToBeInitialized*sizeof(arr[0]));
    printArray(arr, arrLen);
    return 0;
}

Ответ 9

В идеале, вы не можете использовать memset, чтобы установить для всех ваших значений 1.
Потому что memset работает с байтом и устанавливает каждый байт в 1.

memset(hash, 1, cnt);

Поэтому после прочтения значение будет отображаться 16843009 = 0x01010101 = 1000000010000000100000001.
Не 0x00000001
Но если ваш requiremnt только для bool или двоичного значения, тогда мы можем установить, используя стандарт C99 для библиотеки C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>        //Use C99 standard for C language which supports bool variables

int main()
{
    int i, cnt = 5;
    bool *hash = NULL;
    hash = malloc(cnt);

    memset(hash, 1, cnt);
    printf("Hello, World!\n");

    for(i=0; i<cnt; i++)
        printf("%d ", hash[i]);

    return 0;
}

Выход:

Привет, мир!
1 1 1 1 1

Ответ 10

memset((char *)&tab, 0, sizeof(tab));