免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12345
最近访问板块 发新帖
楼主: ccas
打印 上一主题 下一主题

更改数组大小问题??? [复制链接]

论坛徽章:
0
41 [报告]
发表于 2006-08-24 10:01 |只看该作者
其实还是先要算出你的二维数组占用的总空间,然后用这个长度alloca,malloc等,最后按照将你原来的复制过来,当然不能简单地memcpy就行了,要根据维数对应地memcpy。

论坛徽章:
0
42 [报告]
发表于 2006-08-24 11:43 |只看该作者
原帖由 ccas 于 2006-8-23 18:45 发表
如果我定义了一个数组
  int int_ary[3][3]={{1,1,1},
                               {2,2,2},
                               {3,3,3}};
现在要把它扩展成 4行4列,
  int int_ary[4][4]={{1,1,1,NULL},
                               {2,2,2,NULL},
                               {3,3,3,NULL},
                               {NULL,NULL,NULL,NULL}};
用分配空间的语句(alloc,malloc,remalloc等)要怎么写


我个人认为,你所说的“扩展”这个词的含义,其实很值得推敲。
按你的代码中所表现的意思,应该是指“数组的名称不变,但是大小变化了”,不知道我理解的对不对?

如果是这样的话,那么我觉得任何一个函数恐怕都帮不上忙。
因为无论从堆里还是从栈里重新分配一个buffer,你都无法将这个buffer的首地址赋给已经分配了的数组“int_ary”。因为“int_ary”是不能被作为左值来使用的。也就是说它无法被重新赋值,它永远只能指向初始化时被分配的首地址。

如果你真的想实现“数组的名称不变,但是大小变化”,其实方法也很简单,那就是什么都不用做!
因为C编译器虽然分配了固定内存给数组,但通常并不阻止你使用超过这个数组界限的内存空间。举例如下:

  1.         int     i;
  2.         int     arr[10];

  3.         for(i=0; i<15; i++) {
  4.                 arr[i] = i;
  5.         }
  6.         for(i=0; i<15; i++) {
  7.                 printf("%d\n",arr[i]);
  8.         }
复制代码


这个程序是可以编译通过的,而且会按照我们设想的输出。
二维数组和一维一样都是连续的内存空间,所以可以用同样的方法。只不过实现起来会麻烦一些,你可能需要先把原数组的内容拷贝到别的内存空间,然后再按照某种方法拷贝回来并重新组织。

但是从编程的角度来说,上面的方法应该是被摒弃的!原因嘛大家肯定都很清楚,我就不多说了。

论坛徽章:
0
43 [报告]
发表于 2006-08-24 12:35 |只看该作者
嗯,你说的不错,是可以有技巧的。不过如果这样写,在函数里会出现堆栈溢出的,如果在数据区分配的也不怎么行吧。呵呵,你说的对,我们应该摒弃这种写法。
        int     i;
        int     arr[10];

        for(i=0; i<15; i++) {
                arr[i] = i;
        }
        for(i=0; i<15; i++) {
                printf("%d\n",arr[i]);
        }

论坛徽章:
0
44 [报告]
发表于 2006-08-24 13:46 |只看该作者
原帖由 harly 于 2006-8-24 12:35 发表
嗯,你说的不错,是可以有技巧的。不过如果这样写,在函数里会出现堆栈溢出的,如果在数据区分配的也不怎么行吧。呵呵,你说的对,我们应该摒弃这种写法。
        int     i;
        int     arr[10];

    ...



这种方法对于函数内部的数组(分配在栈内)和全局数组(分配在数据区内)都是可用的。

这种程序可能你运行很长时间都不会有问题,突然有一天却coredump了。
像我这种写法,在做代码review时很容易被发现。但是如果把这个数组名作为一个指针使用,就很可能会忽略掉边界检查。

论坛徽章:
0
45 [报告]
发表于 2006-08-24 14:13 |只看该作者
原帖由 羽人 于 2006-8-24 13:46 发表



这种方法对于函数内部的数组(分配在栈内)和全局数组(分配在数据区内)都是可用的。

这种程序可能你运行很长时间都不会有问题,突然有一天却coredump了。
像我这种写法,在做代码review时很容易被发现 ...


兄弟,不一定噢,刚才情况不溢出,是你的循环次数少了点,我改成了55,就覆盖了堆栈里面的eip了,你运行下看看。

#include<stdio.h>

int main()
{
   
        int     arr[10];
        int     i;
        for(i=0; i<55; i++) {
                *(arr+i) = i;
        }
        for(i=0; i<55; i++) {
                printf("%d\n",*(arr+i));
        }
        printf("It can not be run in my os\n" ) ;
        getchar();
}

兄弟,帮个忙,告诉我怎么贴代码。。

[ 本帖最后由 harly 于 2006-8-24 14:15 编辑 ]

论坛徽章:
0
46 [报告]
发表于 2006-08-24 16:22 |只看该作者
原帖由 harly 于 2006-8-24 14:13 发表


兄弟,不一定噢,刚才情况不溢出,是你的循环次数少了点,我改成了55,就覆盖了堆栈里面的eip了,你运行下看看。

#include<stdio.h>

int main()
{
   
        int     arr[10];
        in ...



是这样的。
所以我在帖子里说“这种程序可能你运行很长时间都不会有问题,突然有一天却coredump了”,就是说的这种情况。当超出数组的界限小的时候,不会有问题;超出的多了,肯定出错。

粘贴“代码”的方法,我通过站内短信发给你了。

论坛徽章:
0
47 [报告]
发表于 2006-08-24 17:33 |只看该作者
  1. 兄弟,谢谢你了噢。现在终于明白了:lol:
复制代码

论坛徽章:
0
48 [报告]
发表于 2006-08-24 19:51 |只看该作者
vector

论坛徽章:
0
49 [报告]
发表于 2006-08-24 21:05 |只看该作者
用 realloc 能保证原来数组中的值还在正确的位置上吗?

论坛徽章:
0
50 [报告]
发表于 2006-08-24 21:12 |只看该作者
原帖由 happer_xc 于 2006-8-24 21:05 发表
用 realloc 能保证原来数组中的值还在正确的位置上吗?


To: happer_xc

如果是实现多维数组转化成一维用malloc等来实现,用realloc不能让新生成的多维满足原来维数间的对应关系。因此你要手工复制,所以我觉得没必要用realloc,可以继续考虑用malloc。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP