算法导论小结(5-花絮)-散列表

By:             潘云登

Date:          2009-7-18

Email:         intrepyd@gmail.com

Homepage: http://blog.csdn.net/intrepyd

Copyright: 该文章版权由潘云登所有。可在非商业目的下任意传播和复制。

对于商业目的下对本文的任何行为需经作者同意。


写在前面

本文记录了一个在实现散列表的过程中出现的错误。原本希望对malloc函数进行封装,结果由于对指针参数的理解不透彻,导致了意想不到的错误。

先来看一下下面的程序。

#include <stdio.h>

 

#define ARRAY_LENGTH 10

 

void new_array(int *array, int length)

{

    int i;

 

    array = malloc(sizeof(int)*length);

    printf("array inside:/n");

    for(i=0; i<length; i++)

    {

                  array[i] = 66;

                  printf("%d ", array[i]);

    }

    printf("/n");

}

 

int main()

{

    int *array, i;

 

    new_array(array, ARRAY_LENGTH);

    printf("array outside:/n");

    for(i=0; i<ARRAY_LENGTH; i++)

                  printf("%d ", array[i]);

    printf("/n");

}

运行结果如下:

array inside:

66 66 66 66 66 66 66 66 66 66

array outside:

1474660693 -1595387050 -2130706297 15169987 1290568448 13649351 -956301312 54341 1170669568 216

在函数中初始化为66的数组变成了这些奇怪的数字。为了查看数组的地址,添加新的打印。

#include <stdio.h>

 

#define ARRAY_LENGTH 10

 

void new_array(int *array, int length)

{

    int i;

 

    printf("inside,before malloc(),array=0x%0xd/n", (int)array);

    array = malloc(sizeof(int)*length);

    printf("array inside:/n");

    for(i=0; i<length; i++)

    {

                  array[i] = 66;

                  printf("%d ", array[i]);

    }

    printf("/n");

    printf("inside,after malloc(),array=0x%0xd/n", (int)array);

}

 

int main()

{

    int *array, i;

 

    printf("outside,before new_array(),array=0x%0xd/n", (int)array);

    new_array(array, ARRAY_LENGTH);

    printf("outside,after new_array(),array=0x%0xd/n", (int)array);

    printf("array outside:/n");

    for(i=0; i<ARRAY_LENGTH; i++)

                  printf("%d ", array[i]);

    printf("/n");

}

运行结果如下:

outside,before new_array(),array=0xb8054870d

inside,before malloc(),array=0xb8054870d

array inside:

66 66 66 66 66 66 66 66 66 66

inside,after malloc(),array=0x90ef008d

outside,after new_array(),array=0xb8054870d

array outside:

1474660693 -1595387050 -2130706297 15169987 1290568448 13649351 -956301312 54341 1170669568 216

终于真相大白,new_array()函数返回后,array的值仍然是0xb8054870d,而不是malloc所申请空间的地址。原来,array本身是一个指针,将其作为参数传递,在调用函数内,可以修改并保存指针所指向内存空间的内容。然而,指针本身的值仍是按值传递,函数返回后,其值保持不变。这种错误,不仅导致读写错误的内存地址,造成段错误,而且,malloc申请的空间再也无法释放,产生内存泄漏。

为了纠正上述错误,有两种修改方案,具体实现如下:

#include <stdio.h>

 

#define ARRAY_LENGTH 10

 

/*方案1*/

int *correct_new_array(int length)

{

    int i, *temp_array;

 

    temp_array = malloc(sizeof(int)*length);

    for(i=0; i<length; i++)

                  temp_array[i] = 77;

 

    return temp_array;

}

 

/*方案2*/

void correct_new_array_again(int **array, int length)

{

    int i;

 

    *array = malloc(sizeof(int)*length);

    for(i=0; i<length; i++)

                  (*array)[i] = 88;

}

个人比较喜欢方案1,不需要传递指针的指针,发生错误的概率较小。需要注意的是,不要忘了free先前malloc的内存空间,虽然上面的代码并没有列出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值