C问题中的动态内存分配
我试图增加a的记忆,但realloc似乎什么都没做。在第四位,程序崩溃。似乎数字也被放入[0]中,即使计数器增加,也应该是[counter]。我知道我从[1]开始,因为当我完成输入时,我正在[0]中写入计数器本身 printf:Input vector的转换(输入结束时使用除点以外的任何非数字字符) 编辑: 非常感谢。你们的回答都很好 有没有办法找出分配了多少内存空间? 在后面的代码中,我用sizeof(a)/sizeof(float)检查该数组中的元素数量,现在我知道该数组是不正确的。幸运的是,我有一个存储在内存中的计数器,所以我知道我有多少元素,但如果我不存储这些信息,我怎么知道呢C问题中的动态内存分配,c,C,我试图增加a的记忆,但realloc似乎什么都没做。在第四位,程序崩溃。似乎数字也被放入[0]中,即使计数器增加,也应该是[counter]。我知道我从[1]开始,因为当我完成输入时,我正在[0]中写入计数器本身 printf:Input vector的转换(输入结束时使用除点以外的任何非数字字符) 编辑: 非常感谢。你们的回答都很好 有没有办法找出分配了多少内存空间? 在后面的代码中,我用sizeof(a)/sizeof(float)检查该数组中的元素数量,现在我知道该数组是不正确的。幸运的是
a = realloc(a, (sizeof(a) + sizeof(float)));
sizeof(a)
和sizeof(float)
都是常量(在大多数情况下,sizeof(任意)
都是常量)。所以你总是要求同样的内存量
通常情况下,你需要的东西大致如下:
a = realloc(a, counter * sizeof(float));
但是
(计数器+1)
,而不是计数器
,等等a=realloc(a,…)
。查看realloc
如何报告错误(以及在发生错误时如何处理原始内存块)以了解原因sizeof(a)
和sizeof(float)
都是常量(在大多数情况下,sizeof(任意)
都是常量)。所以你总是要求同样的内存量
通常情况下,你需要的东西大致如下:
a = realloc(a, counter * sizeof(float));
但是
(计数器+1)
,而不是计数器
,等等a=realloc(a,…)
。查看realloc
如何报告错误(以及在发生错误时如何处理原始内存块)以了解原因另请参见
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
似乎是一笔不错的交易,但速度很慢。您应该采用类似“当空间用完时,我将使当前使用量翻倍”之类的策略或类似的策略。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
似乎是一笔不错的交易,但速度很慢。你应该采取“当我用完空间时,我会将当前使用量翻倍”之类的策略或类似的策略。不管你怎么想:
if (sizeof(a) == sizeof(float)) {
return NULL;
}
不管你怎么想:
if (sizeof(a) == sizeof(float)) {
return NULL;
}
简而言之,sizeof(a)
不会做你认为它会做的事。a
的类型是*float
,因此它的大小非常小。您需要跟踪数组的长度,并将其乘以sizeof(float)
以获得当前大小。简言之sizeof(a)
并没有达到您认为的效果。a
的类型是*float
,因此它的大小非常小。您需要跟踪数组的长度,并将其乘以sizeof(float)
以获得当前大小。执行以下操作时:
float *a = (float *) malloc(sizeof(float));
...
a = realloc(a, (sizeof(a) + sizeof(float)));
“sizeof(a)”总是返回4(在32位机器上,8在64位机器上)。”尽管它的外观不是一种功能。这是一个算符,它给出了变量的大小。在本例中,“a”只是一个指针。sizeof不会给出a所指向的对象的大小
您需要做的是保留一个长度变量,该变量跟踪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;
当您这样做时:
float *a = (float *) malloc(sizeof(float));
...
a = realloc(a, (sizeof(a) + sizeof(float)));
“sizeof(a)”总是返回4(在32位机器上,8在64位机器上)。”尽管它的外观不是一种功能。这是一个算符,它给出了变量的大小。在本例中,“a”只是一个指针。sizeof不会给出a所指向的对象的大小
您需要做的是保留一个长度变量,该变量跟踪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;
您得到的错误意味着您的堆段中存在缓冲区溢出。这是因为在第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);
}
如您所见,计数器将损坏:)您得到的错误意味着您的堆段中存在缓冲区溢出。这是因为在第15行,您会:
a = realloc(a, (sizeof(a) + sizeof(float)));
sizeof是一个宏函数,它将在编译时起决定作用,而不是在运行时使用计数器