user-0 提问: 如何分配未知长度的数组或者内存空间

回复:
user: user-1
content: 我给你介绍个c的小东东，obstack。grow就行了，比任何stl都好用。

user: user-2
content: STL的vector因为规定是连续空间 ，但又动态大小，就采用了如上策略

user: user-2
content: 其实你可以直接分配一个连续空间，不够的时候直接加倍realloc，最多浪费数据大小一倍空间，最多也就复制32次(32位

user: user-3
content: 引用 13 楼 micklexqg 的回复:个人总结：我觉得还是预定义一个稍大一点的数组是最简单，最有效的解决方法，用拷贝的方法也可以，但是增加了复杂度，而且还要多分配一块内存空间，虽然有释放掉，但是中间处理的时候会同时需要两个内存空间的。。。以上完全是个人感觉。。。 如果想节省空间，就用链表吧 STL的list 如果符合条件，就 push_back 进去，时间复杂度为常数。

user: user-4
content: 引用 3 楼 micklexqg 的回复:[quote=引用 1 楼 qq120848369 的回复:] 内存不够用了可以分配一块更大的，把原先的数据拷贝上去哈。 那不如直接定义一个大的数组。。。[/quote] 你怎么知道多大叫大的数组？

user: user-5
content: 是不是考虑复杂了？？ 声明一个和原数组一样大的数组不行吗？  因为后申请的数组的肯定是原始数组的子集。

user: user-6
content: 说白了，最底层的内存管理，就是这样： 1、如果要内存连续，最有效的方法就是先算出大小，然后分配； 2、如果大小有变化，那么重新分配，把老数据copy过去； 3、如果嫌麻烦，同时担心内存碎片，分配效率什么的，分配一块非常大内存，自行管理（内存池）；

user: user-7
content: 除了18楼的兄弟，其他人都一帮垃圾 答的什么问题，连边都不靠  楼主的问题，就是不懂数据结构的问题

user: user-8
content: 1）不想用vector 就学习，vector的处理方式，这样C，C++都可以用。 好像是每次满了以后，增加固定字节，比如256 字节 ，或者每次满了以后，加倍数据空间。  2）如果连拷贝数据，都不希望有，那就用数组链表。 满了，再开一个数组。  大概结构如下： 类型定义：  struct block{ T arr[N]; int size; struct block* next; };  实际结构：  arr[N]  +--->arr    +--->arr[N] size    |    size   |    size next--->+    next --+    NULL  数据结构里的链串，就是这么处理的。

user: user-9
content: 引用 楼主 micklexqg 的回复:是这样的，数组都是需要知道长度的，就算是动态数组，也需要知道动态分配的长度，而这里的情况是这样的，在一个循环体里，有判断比较，如果满足条件就把数据保存下来，不满足跳过下一步，所以整个数据的长度只有循环体结束了之后才会知道。首先，我不想直接定义一个很长的数组，其次，我不想执行两次循环，即不想先算出长度，在存储数据，而且，即使是连续两次new或者malloc，内存空间也应该不会是连续的，所以只要满足条件就new的做法是不对的，有人告诉我用链表或者vector，但是这个不是很懂，我想知道，用C或者数组能不能解决？求告知。。。 不用多想了，这种情况下用vector是非常适合的，只是push的时候要成組数据，不要单个。

user: user-10
content: 赵老师贴的代码只是给你个malloc、realloc、free函数用法例子，是让你自己用这三个函数，先malloc，每次需要增加再realloc，用完记得free

user: user-11
content: 自己写一个内存池，分配一块超级大的内存，随便你怎么用，用完了告诉内存池用了多少。内存池自动回收剩下的内存用于下次分配。  这个办法是不是很傻

user: user-12
content: HeapReAlloc

user: user-0
content: 个人总结：我觉得还是预定义一个稍大一点的数组是最简单，最有效的解决方法，用拷贝的方法也可以，但是增加了复杂度，而且还要多分配一块内存空间，虽然有释放掉，但是中间处理的时候会同时需要两个内存空间的。。。以上完全是个人感觉。。。

user: user-13
content: 代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。

user: user-0
content: 引用 9 楼 zhao4zhong1 的回复:malloc realloc free 仅供参考//输出PROG中有但LIST中没有的文本行，即集合PROG-LIST #include <stdio.h> #include <string.h> #include <stdlib.h> #include <search.h> #define MAXCHARS 512 int MAXLINES=10000,MAXLINES2; char *buf,*buf2; char PROG[256]="PROG";//程序Program需要的文件列表 char LIST[256]="LIST";//dir /b /s生成的实际文件列表List FILE *fp,*fl; int i,c,n,L,hh; int ignore_case=0; char ln[MAXCHARS]; int icompare(const void *arg1,const void *arg2) {    return stricmp((char *)arg1,(char *)arg2); } int compare(const void *arg1,const void *arg2) {    return strcmp((char *)arg1,(char *)arg2); } int main(int argc,char **argv) {     if (argc>1) strcpy(PROG,argv[1]);//命令行参数1覆盖PROG     if (argc>2) strcpy(LIST,argv[2]);//命令行参数2覆盖LIST     if (argc>3) ignore_case=1;//若存在命令行参数3，忽略大小写     if ((fl=fopen(LIST,"rt"))==NULL) {         fprintf(stderr,"Can not open %s\n",LIST);         fprintf(stderr,"Usage: %s [PROG] [LIST] [-i]\n",argv[0]);         return 1;     }     if ((fp=fopen(PROG,"rt"))==NULL) {         fclose(fl);         fprintf(stderr,"Can not open %s\n",PROG);         fprintf(stderr,"Usage: %s [PROG] [LIST] [-i]\n",argv[0]);         return 2;     }     buf=(char *)malloc(MAXLINES*MAXCHARS);     if (NULL==buf) {         fclose(fl);         fclose(fp);         fprintf(stderr,"Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES,MAXCHARS);         return 4;     }     n=0;     hh=0;     i=0;     while (1) {         if (fgets(ln,MAXCHARS,fl)==NULL) break;//         hh++;         L=strlen(ln)-1;         if ('\n'!=ln[L]) {//超长行忽略后面内容             fprintf(stderr,"%s Line %d too long(>%d),spilth ignored.\n",LIST,hh,MAXCHARS);             while (1) {                 c=fgetc(fl);                 if ('\n'==c || EOF==c) break;//             }         }         while (1) {//去掉行尾的'\n'和空格             if ('\n'==ln[L] || ' '==ln[L]) {                 ln[L]=0;                 L--;                 if (L<0) break;//             } else break;//         }         if (L>=0) {             strcpy(buf+i,ln);i+=MAXCHARS;             n++;             if (n>=MAXLINES) {                 MAXLINES2=MAXLINES*2;                 if (MAXLINES2==1280000) MAXLINES2=2500000;                 buf2=(char *)realloc(buf,MAXLINES2*MAXCHARS);                 if (NULL==buf2) {                     free(buf);                     fclose(fl);                     fclose(fp);                     fprintf(stderr,"Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES2,MAXCHARS);                     return 5;                 }                 buf=buf2;                 MAXLINES=MAXLINES2;             }         }     }     fclose(fl);     if (ignore_case) qsort(buf,n,MAXCHARS,icompare);     else qsort(buf,n,MAXCHARS,compare);     hh=0;     while (1) {         if (fgets(ln,MAXCHARS,fp)==NULL) break;//         hh++;         L=strlen(ln)-1;         if ('\n'!=ln[L]) {//超长行忽略后面内容             fprintf(stderr,"%s Line %d too long(>%d),spilth ignored.\n",PROG,hh,MAXCHARS);             while (1) {                 c=fgetc(fp);                 if ('\n'==c || EOF==c) break;//             }         }         while (1) {//去掉行尾的'\n'和空格             if ('\n'==ln[L] || ' '==ln[L]) {                 ln[L]=0;                 L--;                 if (L<0) break;//             } else break;//         }         if (L>=0) {             if (ignore_case) {                 if (NULL==bsearch(ln,buf,n,MAXCHARS,icompare)) printf("%s\n",ln);             } else {                 if (NULL==bsearch(ln,buf,n,MAXCHARS,compare)) printf("%s\n",ln);             }         }     }     fclose(fp);     free(buf);     return 0; }  好难啊，看不懂、、、

user: user-14
content: 栈空间较小，最好不要直接定义一个大数组，试试realloc看看合不合用先...

user: user-13
content: malloc realloc free 仅供参考//输出PROG中有但LIST中没有的文本行，即集合PROG-LIST #include <stdio.h> #include <string.h> #include <stdlib.h> #include <search.h> #define MAXCHARS 512 int MAXLINES=10000,MAXLINES2; char *buf,*buf2; char PROG[256]="PROG";//程序Program需要的文件列表 char LIST[256]="LIST";//dir /b /s生成的实际文件列表List FILE *fp,*fl; int i,c,n,L,hh; int ignore_case=0; char ln[MAXCHARS]; int icompare(const void *arg1,const void *arg2) {    return stricmp((char *)arg1,(char *)arg2); } int compare(const void *arg1,const void *arg2) {    return strcmp((char *)arg1,(char *)arg2); } int main(int argc,char **argv) {     if (argc>1) strcpy(PROG,argv[1]);//命令行参数1覆盖PROG     if (argc>2) strcpy(LIST,argv[2]);//命令行参数2覆盖LIST     if (argc>3) ignore_case=1;//若存在命令行参数3，忽略大小写     if ((fl=fopen(LIST,"rt"))==NULL) {         fprintf(stderr,"Can not open %s\n",LIST);         fprintf(stderr,"Usage: %s [PROG] [LIST] [-i]\n",argv[0]);         return 1;     }     if ((fp=fopen(PROG,"rt"))==NULL) {         fclose(fl);         fprintf(stderr,"Can not open %s\n",PROG);         fprintf(stderr,"Usage: %s [PROG] [LIST] [-i]\n",argv[0]);         return 2;     }     buf=(char *)malloc(MAXLINES*MAXCHARS);     if (NULL==buf) {         fclose(fl);         fclose(fp);         fprintf(stderr,"Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES,MAXCHARS);         return 4;     }     n=0;     hh=0;     i=0;     while (1) {         if (fgets(ln,MAXCHARS,fl)==NULL) break;//         hh++;         L=strlen(ln)-1;         if ('\n'!=ln[L]) {//超长行忽略后面内容             fprintf(stderr,"%s Line %d too long(>%d),spilth ignored.\n",LIST,hh,MAXCHARS);             while (1) {                 c=fgetc(fl);                 if ('\n'==c || EOF==c) break;//             }         }         while (1) {//去掉行尾的'\n'和空格             if ('\n'==ln[L] || ' '==ln[L]) {                 ln[L]=0;                 L--;                 if (L<0) break;//             } else break;//         }         if (L>=0) {             strcpy(buf+i,ln);i+=MAXCHARS;             n++;             if (n>=MAXLINES) {                 MAXLINES2=MAXLINES*2;                 if (MAXLINES2==1280000) MAXLINES2=2500000;                 buf2=(char *)realloc(buf,MAXLINES2*MAXCHARS);                 if (NULL==buf2) {                     free(buf);                     fclose(fl);                     fclose(fp);                     fprintf(stderr,"Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES2,MAXCHARS);                     return 5;                 }                 buf=buf2;                 MAXLINES=MAXLINES2;             }         }     }     fclose(fl);     if (ignore_case) qsort(buf,n,MAXCHARS,icompare);     else qsort(buf,n,MAXCHARS,compare);     hh=0;     while (1) {         if (fgets(ln,MAXCHARS,fp)==NULL) break;//         hh++;         L=strlen(ln)-1;         if ('\n'!=ln[L]) {//超长行忽略后面内容             fprintf(stderr,"%s Line %d too long(>%d),spilth ignored.\n",PROG,hh,MAXCHARS);             while (1) {                 c=fgetc(fp);                 if ('\n'==c || EOF==c) break;//             }         }         while (1) {//去掉行尾的'\n'和空格             if ('\n'==ln[L] || ' '==ln[L]) {                 ln[L]=0;                 L--;                 if (L<0) break;//             } else break;//         }         if (L>=0) {             if (ignore_case) {                 if (NULL==bsearch(ln,buf,n,MAXCHARS,icompare)) printf("%s\n",ln);             } else {                 if (NULL==bsearch(ln,buf,n,MAXCHARS,compare)) printf("%s\n",ln);             }         }     }     fclose(fp);     free(buf);     return 0; }

user: user-0
content: 引用 6 楼 zhou19891113 的回复:[quote=引用 楼主 micklexqg 的回复:] 是这样的，数组都是需要知道长度的，就算是动态数组，也需要知道动态分配的长度，而这里的情况是这样的，在一个循环体里，有判断比较，如果满足条件就把数据保存下来，不满足跳过下一步，所以整个数据的长度只有循环体结束了之后才会知道。首先，我不想直接定义一个很长的数组，其次，我不想执行两次循环，即不想先算出长度，在存储数据，而且，即使是连续两次new或者malloc，内存空间也应该不会是连续的，所以只要满足条件就new的做法是不对的，有人告诉我用链表或者vector，但是这个不是很懂，我想知道，用C或者数组能不能解决？求告知。。。 这一类问题都可以通过合理的设计代码得以解决。[/quote] 可是，应该如何合理地设计代码啊，求告知

user: user-0
content: 引用 4 楼 zhuobattle 的回复:[quote=引用 3 楼 micklexqg 的回复:] [quote=引用 1 楼 qq120848369 的回复:] 内存不够用了可以分配一块更大的，把原先的数据拷贝上去哈。 那不如直接定义一个大的数组。。。[/quote] 第一，你能保证一定足够？ 第二，太大的话，大部分情况就浪费了[/quote] 如果每次都循环都执行拷贝的话，会不会增加复杂度啊