c - C问题中的动态内存分配

标签 c

我正在尝试增加 a 的内存,但 realloc 似乎没有做任何事情。在第 4 个数字程序崩溃。似乎数字也被放入 [0],即使计数器增加并且应该是 [counter]。我知道我从 a[1] 开始,因为当我完成输入时,我正在 a[0] 中写入计数器本身。

printf 的翻译:输入 vector (您以除点之外的任何非数字字符结束输入)。

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

typedef float* vektor;

vektor beriVektor() {
    int counter = 0;
    float zacasna;
    float *a = (float *) malloc(sizeof(float));
    printf("Vpisi vektor (vpis zakljucis s katerim koli nestevilskim znakom razen pike):\n");
    while(scanf("%f", &zacasna)) {
        counter++;
        printf("%d\n", counter);
        printf("%d\n", sizeof(a));
        a = realloc(a, (sizeof(a) + sizeof(float)));
        a[counter] = zacasna;
    }
    if (sizeof(a) == sizeof(float)) {
        return NULL;
    }
    a[0] = counter;
    return a;
}

void izpisiVektor(vektor a) {
    if (a == NULL) {
        return;
    }
    else {
        int velikost = sizeof(a)/sizeof(float);
        for (int i = 0; i < velikost; i++) {
            printf("%f", *(a+i));
        }
    }

}

void main(){
    vektor a = beriVektor();
    izpisiVektor(a);

}

输出:

ragezor@ragezor-VirtualBox:~$ ./dn09.o 
Vpisi vektor (vpis zakljucis s katerim koli nestevilskim znakom razen pike):
1 2 3 4
1
4
2
4
3
4
4
4
*** glibc detected *** ./dn09.o: realloc(): invalid next size: 0x09052008 ***
======= Backtrace: =========
/lib/libc.so.6(+0x6c501)[0x835501]
/lib/libc.so.6(+0x71c6d)[0x83ac6d]
/lib/libc.so.6(realloc+0xe3)[0x83af53]
./dn09.o[0x804850e]
./dn09.o[0x8048595]
/lib/libc.so.6(__libc_start_main+0xe7)[0x7dfce7]
./dn09.o[0x8048411]
======= Memory map: ========
001c9000-001e3000 r-xp 00000000 08:01 393295     /lib/libgcc_s.so.1
001e3000-001e4000 r--p 00019000 08:01 393295     /lib/libgcc_s.so.1
001e4000-001e5000 rw-p 0001a000 08:01 393295     /lib/libgcc_s.so.1
005d5000-005f1000 r-xp 00000000 08:01 393234     /lib/ld-2.12.1.so
005f1000-005f2000 r--p 0001b000 08:01 393234     /lib/ld-2.12.1.so
005f2000-005f3000 rw-p 0001c000 08:01 393234     /lib/ld-2.12.1.so
0069e000-0069f000 r-xp 00000000 00:00 0          [vdso]
007c9000-00920000 r-xp 00000000 08:01 393454     /lib/libc-2.12.1.so
00920000-00922000 r--p 00157000 08:01 393454     /lib/libc-2.12.1.so
00922000-00923000 rw-p 00159000 08:01 393454     /lib/libc-2.12.1.so
00923000-00926000 rw-p 00000000 00:00 0 
08048000-08049000 r-xp 00000000 08:01 140607     /home/ragezor/dn09.o
08049000-0804a000 r--p 00000000 08:01 140607     /home/ragezor/dn09.o
0804a000-0804b000 rw-p 00001000 08:01 140607     /home/ragezor/dn09.o
09052000-09073000 rw-p 00000000 00:00 0          [heap]
b7700000-b7721000 rw-p 00000000 00:00 0 
b7721000-b7800000 ---p 00000000 00:00 0 
b78d9000-b78da000 rw-p 00000000 00:00 0 
b78e7000-b78eb000 rw-p 00000000 00:00 0 
bfc2e000-bfc4f000 rw-p 00000000 00:00 0          [stack]
Aborted

编辑: 谢谢。你们所有人的回答都非常好。

有什么方法可以查明分配给 vektor a 的内存空间有多少? 稍后在代码中,我使用 sizeof(a)/sizeof(float) 检查该数组中的元素数量,现在我知道这是不正确的。幸运的是,我在 a 中存储了计数器,所以我知道我有多少元素,但如果我不存储这些信息,我怎么知道呢?

最佳答案

realloc 不正确。您得到的是您机器上指针的大小,而不是目前已分配空间的大小。

float *a = (float *) malloc(sizeof(float));
/* .... */
a = realloc(a, (sizeof(a) + sizeof(float)));

因此,假设一个float * 占用4 个字节。您将始终分配 4 + sizeof(float),最终您将走出去。您需要跟踪元素的数量,然后:

a = realloc(a, sizeof(float) * (el_no + 1));

当然,更好的形式是:

a = realloc(a, sizeof(*a) * (el_no + 1));

如果您稍后决定更改 a 的类型,您将以这种方式安全。

编辑

附带说明,为每个新元素调用 realloc 似乎很划算,但速度很慢。您应该采用类似“当我用完空间时,我会将当前使用量加倍”或该行中的其他内容的策略。

关于c - C问题中的动态内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5995037/

相关文章:

c - 如何从一个 C 文件到另一个 C 文件访问整数数组?

c - 运算符 '>>' 和 '&' 的未经允许的操作数 (MISRA C)

c++ - 将虚拟地址的逻辑地址转换为物理地址

c - 我的 C 程序跳过 fprinf 并且没有将数据写入指定文件,特别是在第一个 printf 之后

c - Valgrind 在检查内存泄漏时可能丢失消息 - C

c - 为什么使用 C printf 格式 "0x"打印 0(零)时没有前导 "%#x"?

C++:初始化在头文件中声明的模板构造函数/例程?

c++ - 具有线程本地存储的自定义内存管理器

c - 静态链接库。 c编译

c - 如何将代码点 32 位整数数组(UTF-32?)转换为 Windows native 字符串?