我正在努力增加对a的记忆,但realloc似乎没有做任何事情。在第4个数字程序崩溃。即使计数器增加并且应该是[计数器],似乎也将数字放入[0]。我知道我从[1]开始,因为当我完成输入时,我正在[0]中写入计数器。
printf的翻译:输入向量(使用除点之外的任何非数字字符结束输入。)
#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
编辑: 谢谢。你们所有人都给出了非常好的答案。
有没有办法找出分配了多少内存空间? 稍后在代码中我用sizeof(a)/ sizeof(float)检查该数组中元素的数量,现在我理解这是元素。幸运的是,我有一个计数器存储在一个所以我知道我有多少元素,但如果我不知道存储的信息我怎么知道?
答案 0 :(得分:3)
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
可能看起来很划算,但速度很慢。您应该采用一种策略,例如“当我用完空间时,我会将当前使用量加倍”或该行中的某些内容。
答案 1 :(得分:1)
无论你怎么想:
if (sizeof(a) == sizeof(float)) {
return NULL;
}
正在做,事实并非如此。
答案 2 :(得分:1)
当你这样做时:
float *a = (float *) malloc(sizeof(float));
...
a = realloc(a, (sizeof(a) + sizeof(float)));
您需要做的是保留一个长度变量,以跟踪malloc / realloc分配的块中的浮点数。
int N_floats = 0 ;
float *a = (float *)malloc(0) ;
/* add a float */
a = (float *)realloc(a, (N_floats+1)*sizeof(float)) ;
a[N_floats] = 1.0 ;
N_floats += 1;
答案 3 :(得分:0)
a = realloc(a, (sizeof(a) + sizeof(float)));
sizeof(a)
和sizeof(float)
都是常量(大多数情况下,sizeof(anything)
是常量)。所以你总是在这里要求相同数量的内存。
通常你需要的东西是
a = realloc(a, counter * sizeof(float));
但
(counter + 1)
而不是counter
,等等。a = realloc(a, ...)
。查看realloc
如何报告错误(以及在发生错误时它对原始内存块的作用)以了解原因。答案 4 :(得分:0)
简而言之,sizeof(a)
并不符合您的想法。 a
的类型为*float
,因此其大小非常小。您需要跟踪数组的长度并将其乘以sizeof(float)
以获得当前大小。
答案 5 :(得分:0)
您获得的错误意味着您的堆段中存在缓冲区溢出。这是因为在第15行你做了:
a = realloc(a, (sizeof(a) + sizeof(float)));
sizeof是一个宏函数,它将在编译时阻止而不是运行时,您应该使用计数器来计算新读取所需的大小。尝试这样的事情:
a = realloc(a, (sizeof(*a) * (counter + 1))); // + one for the counter itself
此外,您需要记住,在第21行,您将整数(计数器)转换为浮动,这将导致计数器换行并以负值重新启动。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int value = 822222233;
float flt = value;
printf("equal: %s\nvalue = %d\nflt = %f\n(int)flt = %d", value == flt ? "true" : "false", value, flt, ((int)flt));
exit(0);
}
输出:
gcc -m32 -O3 -Wall -Wextra -std=c99 test.c && ./a.out
equal: true
value = 822222233
flt = 822222208.000000
(int)flt = 822222208
你可以看到你的柜台会腐败:)