2 回答
TA贡献1864条经验 获得超2个赞
atmystate建议使用的realloc函数的实质是,如果原来的数组a的大小不够,将会重新分配一个指定的内存大小(这个内存大小一定要大于之前a的大小),然后将原来数组a已有的数据拷贝到新分配的内存中,然后释放原来a的内存,最后将新分配的内存地址复制给a。在程序运行期间,会一直执行这样的过程,直到结束,这里实际上已经没有数组的含义所在了,a在声明的时候就是声明成一个指针,只是a指向的内存中的数据,可以用数组的形式去访问(偏移访问)。
其实,从数组的含义就可以知道,数组是一段连续的内存,里面存放数据类型相同的数据,这样就可以用数组下标,实际上是数组首地址偏移去访问数据,因为每次偏移的大小是一样的。如果采用动态分配,分配的内存基本上完全不会(之所以说基本上完全不会,是因为内存的分配是由操作系统的内存管理机制去操作的,不是我们能左右的,会的概率相当相当小)紧接着已有的数组内存空间的末尾追加。所以realloc实质是绕弯的,但也是必然的。
还有一种可以考虑的,是变长数组。但是变长数组也有自己的缺点,并且实际上也是指针和数组的混用。
可以看看下面的代码。代码中a就是一个变长数组。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#define MAX_NUM 1000
int main(void)
{
char r[]="532sr4544dsfsdf9j00009dfjs8ljol9ljoj1ljljl2ljlj0",*p = 0;
int *b=0, i=0, iCount=0, *pTem[MAX_NUM]={0}, *a[1]={0};
p=r;
while(*p!='\0')
{
if(*p>='0' && *p<='9')
{
if(!(b=(int *)malloc(sizeof(int))))
{
printf("OOXX\n");
return -1;
}
*b=0;
*b=*p-'0';
pTem[iCount]=b;
iCount++;
}
p++;
}
printf("找到个数%d\n",iCount);
a[0] = (int*)malloc(iCount*sizeof(int*));
memcpy(&a[0], pTem, sizeof(int)*iCount);
while(i < iCount){
printf("%d\n",*a[i]);
free(a[i]);
i++;
}
if (0!=a[0])
{
free(a[0]);
}
getchar();
}
这段代码采用了一个pTem来暂时存放结果值,最后将其一并拷贝到数组a中,a定义的大小为1,但实际上可以越界访问全部数据。这个要好好体会。为了不出现越界错误,变长数组在使用的时候,一般会配备一个记录变长数组实际大小的变量,代码中的iCount就是这个变量。
还有一个缺点是pTem的大小由宏定义的MAX_NUM来确定,这是一个局部变量,我这里宏定义MAX_NUM为1000,实际中的需求有可能超过1000这个大小,只需修改宏定义的值,将1000继续变大。这样的话,有两个弊端,一是代码编译连接以后,对于程序而言,能搜索的数字数量就被MAX_NUM限制了,要想支持更大的搜索数量,就必须修改代码,重新编译程序。二是如果MAX_NUM的值过大,有可能造成栈溢出。比方说MAX_NUM的值为1024*1024*2,假设某linux系统中,如果限制了栈大小为1M,那么就会溢出了。
所以,使用realloc也好,使用动态数组也好,都有各自的弊端。
那么使用像链表这样的不是连续内存空间的数据结构吧。链表中的数据区域存放一个搜索结果的指针,分配链表的时候将之分配为全局或者malloc分配,以避免栈溢出。最后的结果输出时遍历链表。
TA贡献1839条经验 获得超15个赞
可以参考下面的程序,
其中用到了realloc,可以将分配的空间动态的增长,先分配10个每当空间不够再申请10个
int main()
{
int *a;
int c = 0;
char r[]="532sr4544dsfsdf9j00009dfjs8ljol9ljoj1ljljl2ljlj0",*p;
a = (int*)malloc(sizeof(int)*10);
p = r;
while (*p)
{
if (*p >= '0' && *p <= '9')
{
int d = *p - '0';
p++;
while (*p >= '0' && *p <= '9')
{
d = d*10+(*p - '0');
p++;
}
if (c > 0 && c %10 == 0)
{
a = (int*)realloc(a, (c/10+1)*10*sizeof(int));
}
a[c++] = d;
continue;
}
p++;
}
if (c)
{
int i;
printf("Total find:%d\n", c);
for (i=0;i<c;i++)
{
printf("%d: %d\n", i+1, a[i]);
}
}
free(a);
return 0;
}
添加回答
举报