学不死就死里xue 发表于 2023-5-2 00:10:03

动态存储

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 10
int main()
{
        int *ptr=NULL;
        int i;
        ptr=(int *)malloc(sizeof(int));
       
        if(ptr==NULL)
        {
                exit(1);
        }
        memset(ptr,0,sizeof(int));   我没看懂memset函数 ptr 是内存块 0是我要让这个内存块初始的数字 那sizeof那里为啥我不加N乘以字节会出错呢?是因为函数本身有什么要求吗
        for(i=0;i<N;i++)
        {
                printf("%d",ptr);
               
        }
        putchar('\n');
        free(ptr);
        return 0;
}

歌者文明清理员 发表于 2023-5-2 00:10:31

本帖最后由 歌者文明清理员 于 2023-5-2 00:11 编辑

这段代码是动态申请一个长度为1的int类型内存块,即ptr指向的内存块只有一个int类型的空间。在使用这个内存块之前,使用memset函数将内存块中每个字节设为0,以确保它的初始值为0。

memset函数的参数是三个,第一个参数是要设置的内存块,第二个参数是要填充内存块的值,第三个参数是填充的字节数。sizeof(int)是int类型所占用的字节数,因为这里只有一个int类型的内存块,填充的字节数就是sizeof(int)。如果使用N乘以字节的方式进行填充,会超出该内存块的范围并导致出错。

后面的循环打印出来的是这个内存块中的数据,因为memset函数将内存块初始化为0,所以打印出来的都是0。

最后,需要释放掉申请的内存块,避免内存泄漏。




memset函数用于将一段内存块中的每一个字节都设置为指定的值。其中,第一个参数指向要操作的内存区域,第二个参数是要设置的值,第三个参数表示要设置的内存块大小。

在这段代码中,ptr是用malloc函数动态分配出的一块内存区域,初始时并没有被赋任何值,因此本质上是“脏数据”,使用memset函数将其清零即可避免使用未初始化的值造成不必要的问题。而sizeof(int)是用于得到int类型的字节大小,用来确定需要清零的内存块的大小,所以在memset函数中不需要乘以N。

isdkz 发表于 2023-5-2 00:17:56

在这段代码中,你提到了 memset 函数。 memset 函数用于将一块内存设置为特定的值。函数原型为:

void *memset(void *s, int c, size_t n);


这里, s 是指向内存区域的指针, c 是要设置的值(一个int), n 是要设置的字节数。 memset 函数将内存区域前n个字节设置为c的值。

在你的代码中,你使用 memset(ptr, 0, sizeof(int)); ,这只会将分配给 ptr 的第一个整数(即前4个字节,如果 int 为4字节)设置为0。因为你只分配了一个整数的空间,所以这里不会出错。但是,当你在 for 循环中访问 ptr] 时(0 <= i < N),由于只分配了一个整数的空间,访问 ptr 到 ptr 都会导致未定义的行为,可能会产生错误。

如果你想分配一个包含 N 个整数的数组,并将所有元素初始化为0,你需要使用 malloc 分配 N 个整数的空间,然后使用 memset 设置整个内存区域。这是如何做到的:

ptr = (int *)malloc(N * sizeof(int));

if (ptr == NULL)
{
    exit(1);
}
memset(ptr, 0, N * sizeof(int));


这里, malloc 会分配 N 个整数的空间,然后 memset 会将整个内存区域设置为0。这样,你可以在 for 循环中安全地访问 ptr] (0 <= i < N)。

sfqxx 发表于 2023-5-2 00:21:06

这是一段使用 `malloc()` 函数从堆中分配动态内存的 c 代码,它使用了 `memset()` 函数来将分配的内存块初始化为零。下面回答您的问题:

- `memset()` 函数的作用是将一段内存块中的每个字节都赋值为给定的值。在这段代码中,`memset(ptr,0,sizeof(int))` 的意思是将指针变量 `ptr` 所指向的内存块的第一个字节赋值为 0,该内存块的总大小为 `sizeof(int)` 个字节。
- `sizeof()` 运算符返回一个类型或变量所占用的字节数。在这段代码中,`sizeof(int)` 表示整型变量所占用的字节数,通常是 4 个字节。因为你是想要抹去整个动态内存的初始值,而不是仅仅抹去前面的若干个元素,所以只需要使用 `sizeof(int)` 而不是 `sizeof(int) * n`。

最后提醒,这段代码实际上只输出了一个数字 0,并没有输出 10 个相邻的 0,这是因为你只分配了一个 `int` 类型的内存块,实际上只有第一个 `ptr` 元素被赋值为 0,剩下的 `ptr` 到 `ptr` 都是未定义的。
有用请设置最佳答案

歌者文明清理员 发表于 2023-5-2 00:34:34

sfqxx 发表于 2023-5-2 00:21
这是一段使用 `malloc()` 函数从堆中分配动态内存的 c 代码,它使用了 `memset()` 函数来将分配的内存块初 ...

你不也不睡觉吗{:10_257:}

学不死就死里xue 发表于 2023-5-2 01:13:56

isdkz 发表于 2023-5-2 00:17
在这段代码中,你提到了 memset 函数。 memset 函数用于将一块内存设置为特定的值。函数原型为:




大佬我那个0那里还是不懂
那个是不是我可以理解为就是将这个内存区域设置为0的意思
那如果我把值换成1,2,3这些呢 为啥出现了超级大的数字

isdkz 发表于 2023-5-2 01:24:53

学不死就死里xue 发表于 2023-5-2 01:13
大佬我那个0那里还是不懂
那个是不是我可以理解为就是将这个内存区域设置为0的意思
那如果我把值换成1 ...

是的, memset 函数的第二个参数(在你的例子中为0)是一个整数,该函数将内存区域的每个字节设置为该整数的最低有效字节。

在C语言中, int 类型通常占用4个字节(32位),而 memset 设置的是每个字节的值,而不是整个 int 。如果你将 memset 的第二个参数更改为1、2、3等,每个字节将被设置为该值,而不是整个整数。因此,你可能会看到一些看似非常大的数字。

例如,如果你使用 memset(ptr, 1, N * sizeof(int)); ,每个字节将被设置为 0x01 。在大多数系统上,这将导致整数值为 0x01010101 ,即十进制的16843009。

如果你想用一个特定的整数值初始化数组,你可以使用 for 循环来设置每个元素。例如,将数组初始化为2:

for (i = 0; i < N; i++)
{
    ptr = 2;
}


这样,你可以将数组的每个元素设置为你想要的任何整数值。

陶远航 发表于 2023-5-2 07:38:10

memset 是一个 C 库函数,用于将一块内存区域设置为特定的值。在这段代码中,memset 被用于将指针 ptr 所指向的内存块设置为 0。memset 的第一个参数是指向内存块的指针,第二个参数是要设置的值(在这里是 0),第三个参数是内存块的大小(以字节为单位)。

memset 调用中没有使用 N 作为内存块的大小,是因为 N 并不一定是用 malloc 分配的内存块的大小。在这段代码中,只分配了一个 int,所以内存块的大小是 sizeof(int) 字节。如果在 memset 调用中使用 N 而不是 sizeof(int),则 memset 将写入超出分配的内存块,可能导致未定义的行为。

sfqxx 发表于 2023-5-2 11:06:45

歌者文明清理员 发表于 2023-5-2 00:34
你不也不睡觉吗

e
页: [1]
查看完整版本: 动态存储