鱼C论坛

 找回密码
 立即注册
查看: 1102|回复: 6

[已解决]依旧是C语言内存问题

[复制链接]
发表于 2021-10-20 17:40:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

int main(void){
    int *p;
    int l = 0;

    p = malloc(sizeof(int) * 1);

    printf("enter some int: ");
    while (scanf("%d", &p[l++]) && getchar() != '\n'){
        continue;
    }

    for (int i = 0; i < l; i++)
        printf("%d ", p[i]);

    return 0;
}

我只给分配了一个整数的内存空间, 可是我在输入的时候即使输入20个整数,也正常读取并存储了,这又是为什么啊。真的是,说C严谨吧编译起来运行又有这么多不确定性的东西,说C不严谨吧,C的代码又告诉我它是严谨的,真的好烦啊。
最佳答案
2021-10-20 17:55:56
本帖最后由 人造人 于 2021-10-20 17:58 编辑

这样会覆盖到后面的东西,对于你的这个程序来说,后面没有东西了
看下面的程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void){
    int *p;
    int l = 0;

    p = malloc(sizeof(int) * 1);
    int *temp = malloc(0x10);

    printf("enter some int: ");
    while (scanf("%d", &p[l++]) && getchar() != '\n'){
        continue;
    }

    for (int i = 0; i < l; i++)
        printf("%d \n", p[i]);

    memset(temp, 0xff, 0x10);

    printf("\n");
    for (int i = 0; i < l; i++)
        printf("%d \n", p[i]);

    printf("%p\n", p);
    printf("%p\n", temp);

    return 0;
}
$ ./main
enter some int: 123 123 123 123 123 123 123 123 123 123
123
123
123
123
123
123
123
123
123
123

123
123
123
123
123
123
123
123
-1
-1
0x800038c20
0x800038c40

对于我这边,两次 malloc 之间空了 32 个字节(不同的环境估计是不一样)
也就是说输入超过 32 个字节就覆盖到了下一个 malloc 的位置
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-10-20 17:55:56 | 显示全部楼层    本楼为最佳答案   
本帖最后由 人造人 于 2021-10-20 17:58 编辑

这样会覆盖到后面的东西,对于你的这个程序来说,后面没有东西了
看下面的程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void){
    int *p;
    int l = 0;

    p = malloc(sizeof(int) * 1);
    int *temp = malloc(0x10);

    printf("enter some int: ");
    while (scanf("%d", &p[l++]) && getchar() != '\n'){
        continue;
    }

    for (int i = 0; i < l; i++)
        printf("%d \n", p[i]);

    memset(temp, 0xff, 0x10);

    printf("\n");
    for (int i = 0; i < l; i++)
        printf("%d \n", p[i]);

    printf("%p\n", p);
    printf("%p\n", temp);

    return 0;
}
$ ./main
enter some int: 123 123 123 123 123 123 123 123 123 123
123
123
123
123
123
123
123
123
123
123

123
123
123
123
123
123
123
123
-1
-1
0x800038c20
0x800038c40

对于我这边,两次 malloc 之间空了 32 个字节(不同的环境估计是不一样)
也就是说输入超过 32 个字节就覆盖到了下一个 malloc 的位置
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-20 17:58:39 | 显示全部楼层
要不bug都是怎么来的,只不过这点代码申请内存的没有多少,如果申请内存多了就冲突了,所以还是码农自己自律,bug才会少些
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-20 18:11:15 | 显示全部楼层
人造人 发表于 2021-10-20 17:55
这样会覆盖到后面的东西,对于你的这个程序来说,后面没有东西了
看下面的程序

老师,你这里面的信息量太多了啊,我太难了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-20 18:17:07 | 显示全部楼层
梦回连营 发表于 2021-10-20 18:11
老师,你这里面的信息量太多了啊,我太难了

先冷静一下,慢慢看,哪里看不懂了再问
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-20 19:46:43 | 显示全部楼层
人造人 发表于 2021-10-20 18:17
先冷静一下,慢慢看,哪里看不懂了再问

老师我悟了。第一个malloc分配内存不满32个字节,第二个malloc就会在第一块内存后面的32个字节开始分配。所以如果在第一块内存存放超过8个int数就会写入到第二块内存区域,这个时候在第二块内存区域存储数据就会修改到第一块内存存储的数据。我在分配好两块内存区域后,在第一块内存放9个int数,第二块区域随后存放8个int数,那么第一块内存的最后一个数字就被覆盖了,其值变成了后面那块区域的第一个数了。非常感谢人造人老师,关于老师代码中的其余内容我会继续学习,继续请教的。
内存分配.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-20 19:56:30 | 显示全部楼层
梦回连营 发表于 2021-10-20 19:46
老师我悟了。第一个malloc分配内存不满32个字节,第二个malloc就会在第一块内存后面的32个字节开始分配。 ...

^_^
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-22 17:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表