Chinaunix首页 | 论坛 | 博客
  • 博客访问: 329535
  • 博文数量: 57
  • 博客积分: 146
  • 博客等级: 入伍新兵
  • 技术积分: 769
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-29 14:57
文章分类
文章存档

2014年(39)

2013年(13)

2012年(5)

我的朋友

分类: C/C++

2014-07-07 13:34:15

整个数组存储在连续地内存中。 

1.使用sizeof来判断数组大小
错误代码

点击(此处)折叠或打开

  1. void clear(int array[]) {
  2. size_t i;
  3. for (i = 0; i < sizeof (array) / sizeof (array[0]); ++i) {
  4. array[i] = 0;
  5. }
  6. }
  7. /* ... */
  8. int dis[12];
  9. clear(dis);
  10. /* ... */
clear函数的参数array是不完整类型且数组array长度没有提供,这里array对于sizeof来说只是一个指针而已。

正确代码:

点击(此处)折叠或打开

  1. void clear(int array[], size_t size) {
  2. size_t i;
  3. for (i = 0; i < size; i++) {
  4. array[i] = 0;
  5. }
  6. }
  7. /* ... */
  8. int dis[12];
  9. clear(dis, sizeof (dis) / sizeof (dis[0]));
  10. /* ... */

2.确保数组的索引值属于合理范围

错误代码

点击(此处)折叠或打开

  1. int *table = NULL;
  2. int insert_in_table(int pos, int value){
  3. if (!table) {
  4. table = malloc(sizeof(int) * 100);
  5. }
  6. if (pos > 99) {
  7. return -1;
  8. }
  9. table[pos] = value;
  10. return 0;
  11. }
  12. int main(void)
  13. {
  14.     insert_in_table(-200, 1);
  15.     return 0x00;
  16. }
函数insert_in_table()中pos是signed int可以为负数,代码中缺少对pos为负数时的处理。

正确代码:pos声明为unsigned int,加上pos小于0进行判断(若pos改为signed int,代码依然安全)。

点击(此处)折叠或打开

  1. int *table = NULL;
  2. int insert_in_table(unsigned int pos, int value){
  3. if (!table) {
  4. table = malloc(sizeof(int) * 100);
  5. }
  6. if ( (pos < 0) || (pos > 99) ) {
  7. return -1;
  8. }
  9. table[pos] = value;
  10. return 0;
  11. }

3.确保可变长数组的大小参数在有效的范围内
C99标准增加了支持可变长数组或数组的大小是在运行时确定的。可变长数组本质上与普通数组一样,主要的却别在于可变长的数组大小不是一个常量表达式。可变长数组可以定义如下:

点击(此处)折叠或打开

  1. char vla[s]
上述声明变量s存储在栈中,其大小是在运行时确定的。如果供给vla的长度参数是一个不合理的正整数的值,那么该程序以不期望的方式运行。

错误代码:

点击(此处)折叠或打开

  1. void func(size_t s) {
  2. int vla[s];
  3. /* ... */
  4. }
  5. /* ... */
  6. func(size);
  7. /* ... */
代码没有对size进行范围判断,若size为一个很大的正数或一个负数的话,代码都是存在问题的。
正确代码:

点击(此处)折叠或打开

  1. #define MAX_ARRAY 1024
  2. void func(size_t s) {
  3. int vla[s];
  4. /* ... */
  5. }
  6. /* ... */
  7. if (s < MAX_ARRAY && s != 0) {
  8. func(s);
  9. }
  10. else {
  11. /* Handle Error */
  12. }

4.保证数组有充足的空间大小来进行数据拷贝
错误代码:

点击(此处)折叠或打开

  1. void func(int src[], size_t len) {
  2. int dest[256];
  3. memcpy(dest, src, len*sizeof(int));
  4. /* ... */
  5. }
若len*sizeof(int)大于256的话,则会产生缓冲溢出。

正确代码:

点击(此处)折叠或打开

  1. void func(int src[], size_t len) {
  2. int dest[256];
  3. if (len > 256) {
  4. /* Handle Error */
  5. }
  6. memcpy(dest, src, sizeof(int)*len);
  7. /* ... */
  8. free(dest);
  9. }

正确代码2:

点击(此处)折叠或打开

  1. void func(int src[], size_t len)
  2. {
  3. int *dest;
  4. if (sizeof(int) > SIZE_MAX/len) {
  5. /* handle overflow */
  6. }
  7. dest = malloc(sizeof(int)*len);
  8. if (dest == NULL) {
  9. /* Couldn't get the memory - recover */
  10. }
  11. memcpy(dest, src, sizeof(int)*len);
  12. free(dest);
  13. }


5.确保数组类型表达式是兼容的
若两个或多个数组存在不兼容,那么在表达式中使用的话,它可能会导致未定义的行为。使用不兼容的数组类型会导致内存越界的引用.

错误代码

点击(此处)折叠或打开

  1. enum { a = 10, b = 15, c = 20 };
  2. int arr1[c][b];
  3. int (*arr2)[a];
  4. arr2 = arr1; /* Not compatible, because a != b */
 
阅读(579) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~